vgabios-0.7a/0000755000175000017500000000000011653605131013032 5ustar guillemguillemvgabios-0.7a/vbe.c0000644000175000017500000010503711611346001013750 0ustar guillemguillem// ============================================================================================ // // Copyright (C) 2002 Jeroen Janssen // // 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 VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card. // You can NOT drive any physical vga card with it. // // ============================================================================================ // // This VBE Bios is based on information taken from : // - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org // // ============================================================================================ // defines available // disable VESA/VBE2 check in vbe info //#define VBE2_NO_VESA_CHECK #include "vbe.h" #include "vbetables.h" // The current OEM Software Revision of this VBE Bios #define VBE_OEM_SOFTWARE_REV 0x0002; extern char vbebios_copyright; extern char vbebios_vendor_name; extern char vbebios_product_name; extern char vbebios_product_revision; ASM_START // FIXME: 'merge' these (c) etc strings with the vgabios.c strings? _vbebios_copyright: .ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/" .byte 0x00 _vbebios_vendor_name: .ascii "Bochs/Plex86 Developers" .byte 0x00 _vbebios_product_name: .ascii "Bochs/Plex86 VBE Adapter" .byte 0x00 _vbebios_product_revision: .ascii "$Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $" .byte 0x00 _vbebios_info_string: .ascii "Bochs VBE Display Adapter enabled" .byte 0x0a,0x0d .byte 0x0a,0x0d .byte 0x00 _no_vbebios_info_string: .ascii "NO Bochs VBE Support available!" .byte 0x0a,0x0d .byte 0x0a,0x0d .byte 0x00 #if defined(USE_BX_INFO) || defined(DEBUG) msg_vbe_init: .ascii "VBE Bios $Id: vbe.c,v 1.64 2011/07/19 18:25:05 vruppert Exp $" .byte 0x0a,0x0d, 0x00 #endif .align 2 vesa_pm_start: dw vesa_pm_set_window - vesa_pm_start dw vesa_pm_set_display_start - vesa_pm_start dw vesa_pm_unimplemented - vesa_pm_start dw vesa_pm_io_ports_table - vesa_pm_start vesa_pm_io_ports_table: dw VBE_DISPI_IOPORT_INDEX dw VBE_DISPI_IOPORT_INDEX + 1 dw VBE_DISPI_IOPORT_DATA dw VBE_DISPI_IOPORT_DATA + 1 dw 0xffff dw 0xffff USE32 vesa_pm_set_window: cmp bx, #0x00 je vesa_pm_set_display_window1 mov ax, #0x0100 ret vesa_pm_set_display_window1: mov ax, dx push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BANK out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax in ax, dx pop dx cmp dx, ax jne illegal_window mov ax, #0x004f ret illegal_window: mov ax, #0x014f ret vesa_pm_set_display_start: cmp bl, #0x80 je vesa_pm_set_display_start1 cmp bl, #0x00 je vesa_pm_set_display_start1 mov ax, #0x0100 ret vesa_pm_set_display_start1: ; convert offset to (X, Y) coordinate ; (would be simpler to change Bochs VBE API...) push eax push ecx push edx push esi push edi shl edx, #16 and ecx, #0xffff or ecx, edx shl ecx, #2 mov eax, ecx push eax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx movzx ecx, ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BPP out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx movzx esi, ax pop eax cmp esi, #4 jz bpp4_mode add esi, #7 shr esi, #3 imul ecx, esi xor edx, edx div ecx mov edi, eax mov eax, edx xor edx, edx div esi jmp set_xy_regs bpp4_mode: shr ecx, #1 xor edx, edx div ecx mov edi, eax mov eax, edx shl eax, #1 set_xy_regs: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_X_OFFSET out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx mov ax, di push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_Y_OFFSET out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx pop edi pop esi pop edx pop ecx pop eax mov ax, #0x004f ret vesa_pm_unimplemented: mov ax, #0x014f ret USE16 vesa_pm_end: ; DISPI ioport functions dispi_get_id: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_ID out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret dispi_set_id: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_ID out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret ASM_END static void dispi_set_xres(xres) Bit16u xres; { ASM_START push bp mov bp, sp push ax push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_XRES out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA mov ax, 4[bp] ; xres out dx, ax pop dx pop ax pop bp ASM_END } static void dispi_set_yres(yres) Bit16u yres; { outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES); outw(VBE_DISPI_IOPORT_DATA,yres); } static void dispi_set_bpp(bpp) Bit16u bpp; { outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP); outw(VBE_DISPI_IOPORT_DATA,bpp); } ASM_START ; AL = bits per pixel / AH = bytes per pixel dispi_get_bpp: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BPP out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx mov ah, al shr ah, 3 test al, #0x07 jz get_bpp_noinc inc ah get_bpp_noinc: pop dx ret ; get display capabilities _dispi_get_max_xres: push dx push bx call dispi_get_enable mov bx, ax or ax, # VBE_DISPI_GETCAPS call _dispi_set_enable mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_XRES out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx push ax mov ax, bx call _dispi_set_enable pop ax pop bx pop dx ret _dispi_get_max_bpp: push dx push bx call dispi_get_enable mov bx, ax or ax, # VBE_DISPI_GETCAPS call _dispi_set_enable mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BPP out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx push ax mov ax, bx call _dispi_set_enable pop ax pop bx pop dx ret _dispi_set_enable: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_ENABLE out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret dispi_get_enable: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_ENABLE out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret _dispi_set_bank: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BANK out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret dispi_get_bank: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BANK out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret ASM_END static void dispi_set_bank_farcall() { ASM_START cmp bx,#0x0100 je dispi_set_bank_farcall_get or bx,bx jnz dispi_set_bank_farcall_error mov ax,dx push dx push ax mov ax,# VBE_DISPI_INDEX_BANK mov dx,# VBE_DISPI_IOPORT_INDEX out dx,ax pop ax mov dx,# VBE_DISPI_IOPORT_DATA out dx,ax in ax,dx pop dx cmp dx,ax jne dispi_set_bank_farcall_error mov ax, #0x004f retf dispi_set_bank_farcall_get: mov ax,# VBE_DISPI_INDEX_BANK mov dx,# VBE_DISPI_IOPORT_INDEX out dx,ax mov dx,# VBE_DISPI_IOPORT_DATA in ax,dx mov dx,ax retf dispi_set_bank_farcall_error: mov ax,#0x014F retf ASM_END } ASM_START dispi_set_x_offset: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_X_OFFSET out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret dispi_get_x_offset: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_X_OFFSET out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret dispi_set_y_offset: push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_Y_OFFSET out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret dispi_get_y_offset: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_Y_OFFSET out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret vga_set_virt_width: push ax push bx push dx mov bx, ax call dispi_get_bpp cmp al, #0x04 ja set_width_svga shr bx, #1 set_width_svga: shr bx, #3 mov dx, # VGAREG_VGA_CRTC_ADDRESS mov ah, bl mov al, #0x13 out dx, ax pop dx pop bx pop ax ret dispi_set_virt_width: call vga_set_virt_width push dx push ax mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH out dx, ax pop ax mov dx, # VBE_DISPI_IOPORT_DATA out dx, ax pop dx ret dispi_get_virt_width: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret dispi_get_virt_height: push dx mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx pop dx ret _vga_compat_setup: push ax push dx ; set CRT X resolution mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_XRES out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx push ax mov dx, # VGAREG_VGA_CRTC_ADDRESS mov ax, #0x0011 out dx, ax pop ax push ax shr ax, #3 dec ax mov ah, al mov al, #0x01 out dx, ax pop ax call vga_set_virt_width ; set CRT Y resolution mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_YRES out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx dec ax push ax mov dx, # VGAREG_VGA_CRTC_ADDRESS mov ah, al mov al, #0x12 out dx, ax pop ax mov al, #0x07 out dx, al inc dx in al, dx and al, #0xbd test ah, #0x01 jz bit8_clear or al, #0x02 bit8_clear: test ah, #0x02 jz bit9_clear or al, #0x40 bit9_clear: out dx, al ; other settings mov dx, # VGAREG_VGA_CRTC_ADDRESS mov ax, #0x0009 out dx, ax mov al, #0x17 out dx, al mov dx, # VGAREG_VGA_CRTC_DATA in al, dx or al, #0x03 out dx, al mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x10 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx or al, #0x01 mov dx, # VGAREG_ACTL_ADDRESS out dx, al mov al, #0x20 out dx, al mov dx, # VGAREG_GRDC_ADDRESS mov ax, #0x0506 out dx, ax mov dx, # VGAREG_SEQU_ADDRESS mov ax, #0x0f02 out dx, ax ; settings for >= 8bpp mov dx, # VBE_DISPI_IOPORT_INDEX mov ax, # VBE_DISPI_INDEX_BPP out dx, ax mov dx, # VBE_DISPI_IOPORT_DATA in ax, dx cmp al, #0x08 jb vga_compat_end mov dx, # VGAREG_VGA_CRTC_ADDRESS mov al, #0x14 out dx, al mov dx, # VGAREG_VGA_CRTC_DATA in al, dx or al, #0x40 out dx, al mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x10 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx or al, #0x40 mov dx, # VGAREG_ACTL_ADDRESS out dx, al mov al, #0x20 out dx, al mov dx, # VGAREG_SEQU_ADDRESS mov al, #0x04 out dx, al mov dx, # VGAREG_SEQU_DATA in al, dx or al, #0x08 out dx, al mov dx, # VGAREG_GRDC_ADDRESS mov al, #0x05 out dx, al mov dx, # VGAREG_GRDC_DATA in al, dx and al, #0x9f or al, #0x40 out dx, al vga_compat_end: pop dx pop ax ASM_END // ModeInfo helper function static ModeInfoListItem* mode_info_find_mode(mode, using_lfb) Bit16u mode; Boolean using_lfb; { ModeInfoListItem *cur_info=&mode_info_list; while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST) { if (cur_info->mode == mode) { if (!using_lfb) { return cur_info; } else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE) { return cur_info; } else { cur_info++; } } else { cur_info++; } } return 0; } ASM_START ; Has VBE display - Returns true if VBE display detected _vbe_has_vbe_display: push ds push bx mov ax, # BIOSMEM_SEG mov ds, ax mov bx, # BIOSMEM_VBE_FLAG mov al, [bx] and al, #0x01 xor ah, ah pop bx pop ds ret ; VBE Init - Initialise the Vesa Bios Extension Code ; This function does a sanity check on the host side display code interface. vbe_init: mov ax, # VBE_DISPI_ID0 call dispi_set_id call dispi_get_id cmp ax, # VBE_DISPI_ID0 jne no_vbe_interface push ds push bx mov ax, # BIOSMEM_SEG mov ds, ax mov bx, # BIOSMEM_VBE_FLAG mov al, #0x01 mov [bx], al pop bx pop ds mov ax, # VBE_DISPI_ID5 call dispi_set_id no_vbe_interface: #if defined(USE_BX_INFO) || defined(DEBUG) mov bx, #msg_vbe_init push bx call _printf inc sp inc sp #endif ret ; VBE Display Info - Display information on screen about the VBE vbe_display_info: call _vbe_has_vbe_display test ax, ax jz no_vbe_flag mov ax, #0xc000 mov ds, ax mov si, #_vbebios_info_string jmp _display_string no_vbe_flag: mov ax, #0xc000 mov ds, ax mov si, #_no_vbebios_info_string jmp _display_string ; helper function for memory size calculation lmulul: and eax, #0x0000FFFF shl ebx, #16 or eax, ebx SEG SS mul eax, dword ptr [di] mov ebx, eax shr ebx, #16 ret ASM_END /** Function 00h - Return VBE Controller Information * * Input: * AX = 4F00h * ES:DI = Pointer to buffer in which to place VbeInfoBlock structure * (VbeSignature should be VBE2 when VBE 2.0 information is desired and * the info block is 512 bytes in size) * Output: * AX = VBE Return Status * */ void vbe_biosfn_return_controller_information(AX, ES, DI) Bit16u *AX;Bit16u ES;Bit16u DI; { Bit16u ss=get_SS(); VbeInfoBlock vbe_info_block; Bit16u status; Bit16u result; Bit16u vbe2_info; Bit16u cur_mode=0; Bit16u cur_ptr=34; Bit16u size_64k; ModeInfoListItem *cur_info=&mode_info_list; status = read_word(ss, AX); #ifdef DEBUG printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status); #endif vbe2_info = 0; #ifdef VBE2_NO_VESA_CHECK #else // get vbe_info_block into local variable memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block)); // check for VBE2 signature if (((vbe_info_block.VbeSignature[0] == 'V') && (vbe_info_block.VbeSignature[1] == 'B') && (vbe_info_block.VbeSignature[2] == 'E') && (vbe_info_block.VbeSignature[3] == '2')) || ((vbe_info_block.VbeSignature[0] == 'V') && (vbe_info_block.VbeSignature[1] == 'E') && (vbe_info_block.VbeSignature[2] == 'S') && (vbe_info_block.VbeSignature[3] == 'A')) ) { vbe2_info = 1; #ifdef DEBUG printf("VBE correct VESA/VBE2 signature found\n"); #endif } #endif // VBE Signature vbe_info_block.VbeSignature[0] = 'V'; vbe_info_block.VbeSignature[1] = 'E'; vbe_info_block.VbeSignature[2] = 'S'; vbe_info_block.VbeSignature[3] = 'A'; // VBE Version supported vbe_info_block.VbeVersion = 0x0200; // OEM String vbe_info_block.OemStringPtr_Seg = 0xc000; vbe_info_block.OemStringPtr_Off = &vbebios_copyright; // Capabilities vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC; vbe_info_block.Capabilities[1] = 0; vbe_info_block.Capabilities[2] = 0; vbe_info_block.Capabilities[3] = 0; // VBE Video Mode Pointer (dynamicly generated from the mode_info_list) vbe_info_block.VideoModePtr_Seg= ES ; vbe_info_block.VideoModePtr_Off= DI + 34; // VBE Total Memory (in 64k blocks) outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA); if (vbe2_info) { // OEM Stuff vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV; vbe_info_block.OemVendorNamePtr_Seg = 0xc000; vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name; vbe_info_block.OemProductNamePtr_Seg = 0xc000; vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name; vbe_info_block.OemProductRevPtr_Seg = 0xc000; vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision; // copy updates in vbe_info_block back memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block)); } else { // copy updates in vbe_info_block back (VBE 1.x compatibility) memcpyb(ES, DI, ss, &vbe_info_block, 256); } do { size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; if ((cur_info->info.XResolution <= dispi_get_max_xres()) && (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && (size_64k <= vbe_info_block.TotalMemory)) { #ifdef DEBUG printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); #endif write_word(ES, DI + cur_ptr, cur_info->mode); cur_mode++; cur_ptr+=2; } else { #ifdef DEBUG printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel); #endif } cur_info++; } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST); // Add vesa mode list terminator write_word(ES, DI + cur_ptr, cur_info->mode); result = 0x4f; write_word(ss, AX, result); } /** Function 01h - Return VBE Mode Information * * Input: * AX = 4F01h * CX = Mode Number * ES:DI = Pointer to buffer in which to place ModeInfoBlock structure * Output: * AX = VBE Return Status * */ void vbe_biosfn_return_mode_information(AX, CX, ES, DI) Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; { Bit16u result=0x0100; Bit16u ss=get_SS(); ModeInfoBlock info; ModeInfoListItem *cur_info; Boolean using_lfb; Bit16u lfb_addr; #ifdef DEBUG printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX); #endif using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); CX = (CX & 0x1ff); cur_info = mode_info_find_mode(CX, using_lfb, &cur_info); if (cur_info != 0) { #ifdef DEBUG printf("VBE found mode %x\n",CX); #endif memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); if (using_lfb) { info.NumberOfBanks = 1; } #ifdef PCI_VID lfb_addr = pci_get_lfb_addr(PCI_VID); #else lfb_addr = pci_get_lfb_addr(0x1234); // experimental vendor #endif if (lfb_addr > 0) { info.PhysBasePtr = ((Bit32u)lfb_addr << 16); } if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { info.WinFuncPtr = 0xC0000000UL; *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall); } result = 0x4f; } else { #ifdef DEBUG printf("VBE *NOT* found mode %x\n",CX); #endif result = 0x100; } if (result == 0x4f) { // copy updates in mode_info_block back memcpyb(ES, DI, ss, &info, sizeof(info)); } write_word(ss, AX, result); } /** Function 02h - Set VBE Mode * * Input: * AX = 4F02h * BX = Desired Mode to set * ES:DI = Pointer to CRTCInfoBlock structure * Output: * AX = VBE Return Status * */ void vbe_biosfn_set_mode(AX, BX, ES, DI) Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI; { Bit16u ss = get_SS(); Bit16u result; ModeInfoListItem *cur_info; Boolean using_lfb; Bit8u no_clear; Bit8u lfb_flag; using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0; no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0; BX = (BX & 0x1ff); //result=read_word(ss,AX); // check for non vesa mode if (BXinfo.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); #endif // first disable current mode (when switching between vesa modi) dispi_set_enable(VBE_DISPI_DISABLED); if (cur_info->info.BitsPerPixel == 4) { biosfn_set_video_mode(0x6a); } if (cur_info->info.BitsPerPixel == 8) { load_dac_palette(3); } dispi_set_bpp(cur_info->info.BitsPerPixel); dispi_set_xres(cur_info->info.XResolution); dispi_set_yres(cur_info->info.YResolution); dispi_set_bank(0); dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag); vga_compat_setup(); write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX); write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear)); result = 0x4f; } else { #ifdef DEBUG printf("VBE *NOT* found mode %x\n" , BX); #endif result = 0x100; // FIXME: redirect non VBE modi to normal VGA bios operation // (switch back to VGA mode if (BX == 3) result = 0x4f; } write_word(ss, AX, result); } /** Function 03h - Return Current VBE Mode * * Input: * AX = 4F03h * Output: * AX = VBE Return Status * BX = Current VBE Mode * */ ASM_START vbe_biosfn_return_current_mode: push ds mov ax, # BIOSMEM_SEG mov ds, ax call dispi_get_enable and ax, # VBE_DISPI_ENABLED jz no_vbe_mode mov bx, # BIOSMEM_VBE_MODE mov ax, [bx] mov bx, ax jnz vbe_03_ok no_vbe_mode: mov bx, # BIOSMEM_CURRENT_MODE mov al, [bx] mov bl, al xor bh, bh vbe_03_ok: mov ax, #0x004f pop ds ret ASM_END Bit16u vbe_biosfn_read_video_state_size() { return 9 * 2; } void vbe_biosfn_save_video_state(ES, BX) Bit16u ES; Bit16u BX; { Bit16u enable, i; outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); enable = inw(VBE_DISPI_IOPORT_DATA); write_word(ES, BX, enable); BX += 2; if (!(enable & VBE_DISPI_ENABLED)) return; for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { if (i != VBE_DISPI_INDEX_ENABLE) { outw(VBE_DISPI_IOPORT_INDEX, i); write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA)); BX += 2; } } } void vbe_biosfn_restore_video_state(ES, BX) Bit16u ES; Bit16u BX; { Bit16u enable, i; enable = read_word(ES, BX); BX += 2; if (!(enable & VBE_DISPI_ENABLED)) { outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); outw(VBE_DISPI_IOPORT_DATA, enable); } else { outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); BX += 2; outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); BX += 2; outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP); outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); BX += 2; outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); outw(VBE_DISPI_IOPORT_DATA, enable); for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { outw(VBE_DISPI_IOPORT_INDEX, i); outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); BX += 2; } } } /** Function 04h - Save/Restore State * * Input: * AX = 4F04h * DL = 00h Return Save/Restore State buffer size * 01h Save State * 02h Restore State * CX = Requested states * ES:BX = Pointer to buffer (if DL <> 00h) * Output: * AX = VBE Return Status * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h) * */ void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX) Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX; { Bit16u ss=get_SS(); Bit16u result, val; result = 0x4f; switch(GET_DL()) { case 0x00: val = biosfn_read_video_state_size2(CX); #ifdef DEBUG printf("VGA state size=%x\n", val); #endif if (CX & 8) val += vbe_biosfn_read_video_state_size(); write_word(ss, BX, val); break; case 0x01: val = read_word(ss, BX); val = biosfn_save_video_state(CX, ES, val); #ifdef DEBUG printf("VGA save_state offset=%x\n", val); #endif if (CX & 8) vbe_biosfn_save_video_state(ES, val); break; case 0x02: val = read_word(ss, BX); val = biosfn_restore_video_state(CX, ES, val); #ifdef DEBUG printf("VGA restore_state offset=%x\n", val); #endif if (CX & 8) vbe_biosfn_restore_video_state(ES, val); break; default: // function failed result = 0x100; break; } write_word(ss, AX, result); } /** Function 05h - Display Window Control * * Input: * AX = 4F05h * (16-bit) BH = 00h Set memory window * = 01h Get memory window * BL = Window number * = 00h Window A * = 01h Window B * DX = Window number in video memory in window * granularity units (Set Memory Window only) * Note: * If this function is called while in a linear frame buffer mode, * this function must fail with completion code AH=03h * * Output: * AX = VBE Return Status * DX = Window number in window granularity units * (Get Memory Window only) */ ASM_START vbe_biosfn_display_window_control: cmp bl, #0x00 jne vbe_05_failed cmp bh, #0x01 je get_display_window jb set_display_window mov ax, #0x0100 ret set_display_window: mov ax, dx call _dispi_set_bank call dispi_get_bank cmp ax, dx jne vbe_05_failed mov ax, #0x004f ret get_display_window: call dispi_get_bank mov dx, ax mov ax, #0x004f ret vbe_05_failed: mov ax, #0x014f ret ASM_END /** Function 06h - Set/Get Logical Scan Line Length * * Input: * AX = 4F06h * BL = 00h Set Scan Line Length in Pixels * = 01h Get Scan Line Length * = 02h Set Scan Line Length in Bytes * = 03h Get Maximum Scan Line Length * CX = If BL=00h Desired Width in Pixels * If BL=02h Desired Width in Bytes * (Ignored for Get Functions) * * Output: * AX = VBE Return Status * BX = Bytes Per Scan Line * CX = Actual Pixels Per Scan Line * (truncated to nearest complete pixel) * DX = Maximum Number of Scan Lines */ ASM_START vbe_biosfn_set_get_logical_scan_line_length: mov ax, cx cmp bl, #0x01 je get_logical_scan_line_length cmp bl, #0x02 je set_logical_scan_line_bytes jb set_logical_scan_line_pixels mov ax, #0x0100 ret set_logical_scan_line_bytes: push ax call dispi_get_bpp xor bh, bh mov bl, ah or bl, bl jnz no_4bpp_1 shl ax, #3 mov bl, #1 no_4bpp_1: xor dx, dx pop ax div bx set_logical_scan_line_pixels: call dispi_set_virt_width get_logical_scan_line_length: call dispi_get_bpp xor bh, bh mov bl, ah call dispi_get_virt_width mov cx, ax or bl, bl jnz no_4bpp_2 shr ax, #3 mov bl, #1 no_4bpp_2: mul bx mov bx, ax call dispi_get_virt_height mov dx, ax mov ax, #0x004f ret ASM_END /** Function 07h - Set/Get Display Start * * Input(16-bit): * AX = 4F07h * BH = 00h Reserved and must be 00h * BL = 00h Set Display Start * = 01h Get Display Start * = 02h Schedule Display Start (Alternate) * = 03h Schedule Stereoscopic Display Start * = 04h Get Scheduled Display Start Status * = 05h Enable Stereoscopic Mode * = 06h Disable Stereoscopic Mode * = 80h Set Display Start during Vertical Retrace * = 82h Set Display Start during Vertical Retrace (Alternate) * = 83h Set Stereoscopic Display Start during Vertical Retrace * ECX = If BL=02h/82h Display Start Address in bytes * If BL=03h/83h Left Image Start Address in bytes * EDX = If BL=03h/83h Right Image Start Address in bytes * CX = If BL=00h/80h First Displayed Pixel In Scan Line * DX = If BL=00h/80h First Displayed Scan Line * * Output: * AX = VBE Return Status * BH = If BL=01h Reserved and will be 0 * CX = If BL=01h First Displayed Pixel In Scan Line * If BL=04h 0 if flip has not occurred, not 0 if it has * DX = If BL=01h First Displayed Scan Line * * Input(32-bit): * BH = 00h Reserved and must be 00h * BL = 00h Set Display Start * = 80h Set Display Start during Vertical Retrace * CX = Bits 0-15 of display start address * DX = Bits 16-31 of display start address * ES = Selector for memory mapped registers */ ASM_START vbe_biosfn_set_get_display_start: cmp bl, #0x80 je set_display_start cmp bl, #0x01 je get_display_start jb set_display_start mov ax, #0x0100 ret set_display_start: mov ax, cx call dispi_set_x_offset mov ax, dx call dispi_set_y_offset mov ax, #0x004f ret get_display_start: call dispi_get_x_offset mov cx, ax call dispi_get_y_offset mov dx, ax xor bh, bh mov ax, #0x004f ret ASM_END /** Function 08h - Set/Get Dac Palette Format * * Input: * AX = 4F08h * BL = 00h set DAC palette width * = 01h get DAC palette width * BH = If BL=00h: desired number of bits per primary color * Output: * AX = VBE Return Status * BH = current number of bits per primary color (06h = standard VGA) */ ASM_START vbe_biosfn_set_get_dac_palette_format: cmp bl, #0x01 je get_dac_palette_format jb set_dac_palette_format mov ax, #0x0100 ret set_dac_palette_format: call dispi_get_enable cmp bh, #0x06 je set_normal_dac cmp bh, #0x08 jne vbe_08_unsupported or ax, # VBE_DISPI_8BIT_DAC jnz set_dac_mode set_normal_dac: and ax, #~ VBE_DISPI_8BIT_DAC set_dac_mode: call _dispi_set_enable get_dac_palette_format: mov bh, #0x06 call dispi_get_enable and ax, # VBE_DISPI_8BIT_DAC jz vbe_08_ok mov bh, #0x08 vbe_08_ok: mov ax, #0x004f ret vbe_08_unsupported: mov ax, #0x014f ret ASM_END /** Function 09h - Set/Get Palette Data * * Input: * AX = 4F09h * Output: * AX = VBE Return Status * * FIXME: incomplete API description, Input & Output */ void vbe_biosfn_set_get_palette_data(AX) { } /** Function 0Ah - Return VBE Protected Mode Interface * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface * BL = 00h Return protected mode table * * * Output: AX = Status * ES = Real Mode Segment of Table * DI = Offset of Table * CX = Length of Table including protected mode code * (for copying purposes) */ ASM_START vbe_biosfn_return_protected_mode_interface: test bl, bl jnz _fail mov di, #0xc000 mov es, di mov di, # vesa_pm_start mov cx, # vesa_pm_end sub cx, di mov ax, #0x004f ret _fail: mov ax, #0x014f ret ASM_END vgabios-0.7a/COPYING0000644000175000017500000006347407434154024014105 0ustar guillemguillem GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! vgabios-0.7a/vbe.h0000644000175000017500000002654111137104500013756 0ustar guillemguillem#ifndef vbe_h_included #define vbe_h_included #include "vgabios.h" // DISPI helper function void dispi_set_enable(enable); /** VBE int10 API * * See the function descriptions in vbe.c for more information */ Boolean vbe_has_vbe_display(); void vbe_biosfn_return_controller_information(AX, ES, DI); void vbe_biosfn_return_mode_information(AX, CX, ES, DI); void vbe_biosfn_set_mode(AX, BX, ES, DI); void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX); void vbe_biosfn_set_get_palette_data(AX); void vbe_biosfn_return_protected_mode_interface(AX); // The official VBE Information Block typedef struct VbeInfoBlock { Bit8u VbeSignature[4]; Bit16u VbeVersion; Bit16u OemStringPtr_Off; Bit16u OemStringPtr_Seg; Bit8u Capabilities[4]; Bit16u VideoModePtr_Off; Bit16u VideoModePtr_Seg; Bit16u TotalMemory; Bit16u OemSoftwareRev; Bit16u OemVendorNamePtr_Off; Bit16u OemVendorNamePtr_Seg; Bit16u OemProductNamePtr_Off; Bit16u OemProductNamePtr_Seg; Bit16u OemProductRevPtr_Off; Bit16u OemProductRevPtr_Seg; Bit16u Reserved[111]; // used for dynamicly generated mode list Bit8u OemData[256]; } VbeInfoBlock; // This one is for compactly storing a static list of mode info blocks // this saves us 189 bytes per block typedef struct ModeInfoBlockCompact { // Mandatory information for all VBE revisions Bit16u ModeAttributes; Bit8u WinAAttributes; Bit8u WinBAttributes; Bit16u WinGranularity; Bit16u WinSize; Bit16u WinASegment; Bit16u WinBSegment; Bit32u WinFuncPtr; Bit16u BytesPerScanLine; // Mandatory information for VBE 1.2 and above Bit16u XResolution; Bit16u YResolution; Bit8u XCharSize; Bit8u YCharSize; Bit8u NumberOfPlanes; Bit8u BitsPerPixel; Bit8u NumberOfBanks; Bit8u MemoryModel; Bit8u BankSize; Bit8u NumberOfImagePages; Bit8u Reserved_page; // Direct Color fields (required for direct/6 and YUV/7 memory models) Bit8u RedMaskSize; Bit8u RedFieldPosition; Bit8u GreenMaskSize; Bit8u GreenFieldPosition; Bit8u BlueMaskSize; Bit8u BlueFieldPosition; Bit8u RsvdMaskSize; Bit8u RsvdFieldPosition; Bit8u DirectColorModeInfo; // Mandatory information for VBE 2.0 and above Bit32u PhysBasePtr; Bit32u OffScreenMemOffset; Bit16u OffScreenMemSize; // Mandatory information for VBE 3.0 and above Bit16u LinBytesPerScanLine; Bit8u BnkNumberOfPages; Bit8u LinNumberOfPages; Bit8u LinRedMaskSize; Bit8u LinRedFieldPosition; Bit8u LinGreenMaskSize; Bit8u LinGreenFieldPosition; Bit8u LinBlueMaskSize; Bit8u LinBlueFieldPosition; Bit8u LinRsvdMaskSize; Bit8u LinRsvdFieldPosition; Bit32u MaxPixelClock; // Bit8u Reserved[189]; // DO NOT PUT THIS IN HERE because of Compact Mode Info storage in bios } ModeInfoBlockCompact; typedef struct ModeInfoBlock { // Mandatory information for all VBE revisions Bit16u ModeAttributes; Bit8u WinAAttributes; Bit8u WinBAttributes; Bit16u WinGranularity; Bit16u WinSize; Bit16u WinASegment; Bit16u WinBSegment; Bit32u WinFuncPtr; Bit16u BytesPerScanLine; // Mandatory information for VBE 1.2 and above Bit16u XResolution; Bit16u YResolution; Bit8u XCharSize; Bit8u YCharSize; Bit8u NumberOfPlanes; Bit8u BitsPerPixel; Bit8u NumberOfBanks; Bit8u MemoryModel; Bit8u BankSize; Bit8u NumberOfImagePages; Bit8u Reserved_page; // Direct Color fields (required for direct/6 and YUV/7 memory models) Bit8u RedMaskSize; Bit8u RedFieldPosition; Bit8u GreenMaskSize; Bit8u GreenFieldPosition; Bit8u BlueMaskSize; Bit8u BlueFieldPosition; Bit8u RsvdMaskSize; Bit8u RsvdFieldPosition; Bit8u DirectColorModeInfo; // Mandatory information for VBE 2.0 and above Bit32u PhysBasePtr; Bit32u OffScreenMemOffset; Bit16u OffScreenMemSize; // Mandatory information for VBE 3.0 and above Bit16u LinBytesPerScanLine; Bit8u BnkNumberOfPages; Bit8u LinNumberOfPages; Bit8u LinRedMaskSize; Bit8u LinRedFieldPosition; Bit8u LinGreenMaskSize; Bit8u LinGreenFieldPosition; Bit8u LinBlueMaskSize; Bit8u LinBlueFieldPosition; Bit8u LinRsvdMaskSize; Bit8u LinRsvdFieldPosition; Bit32u MaxPixelClock; Bit8u Reserved[189]; } ModeInfoBlock; typedef struct ModeInfoListItem { Bit16u mode; ModeInfoBlockCompact info; } ModeInfoListItem; // VBE Return Status Info // AL #define VBE_RETURN_STATUS_SUPPORTED 0x4F #define VBE_RETURN_STATUS_UNSUPPORTED 0x00 // AH #define VBE_RETURN_STATUS_SUCCESSFULL 0x00 #define VBE_RETURN_STATUS_FAILED 0x01 #define VBE_RETURN_STATUS_NOT_SUPPORTED 0x02 #define VBE_RETURN_STATUS_INVALID 0x03 // VBE Mode Numbers #define VBE_MODE_VESA_DEFINED 0x0100 #define VBE_MODE_REFRESH_RATE_USE_CRTC 0x0800 #define VBE_MODE_LINEAR_FRAME_BUFFER 0x4000 #define VBE_MODE_PRESERVE_DISPLAY_MEMORY 0x8000 // VBE GFX Mode Number #define VBE_VESA_MODE_640X400X8 0x100 #define VBE_VESA_MODE_640X480X8 0x101 #define VBE_VESA_MODE_800X600X4 0x102 #define VBE_VESA_MODE_800X600X8 0x103 #define VBE_VESA_MODE_1024X768X4 0x104 #define VBE_VESA_MODE_1024X768X8 0x105 #define VBE_VESA_MODE_1280X1024X4 0x106 #define VBE_VESA_MODE_1280X1024X8 0x107 #define VBE_VESA_MODE_320X200X1555 0x10D #define VBE_VESA_MODE_320X200X565 0x10E #define VBE_VESA_MODE_320X200X888 0x10F #define VBE_VESA_MODE_640X480X1555 0x110 #define VBE_VESA_MODE_640X480X565 0x111 #define VBE_VESA_MODE_640X480X888 0x112 #define VBE_VESA_MODE_800X600X1555 0x113 #define VBE_VESA_MODE_800X600X565 0x114 #define VBE_VESA_MODE_800X600X888 0x115 #define VBE_VESA_MODE_1024X768X1555 0x116 #define VBE_VESA_MODE_1024X768X565 0x117 #define VBE_VESA_MODE_1024X768X888 0x118 #define VBE_VESA_MODE_1280X1024X1555 0x119 #define VBE_VESA_MODE_1280X1024X565 0x11A #define VBE_VESA_MODE_1280X1024X888 0x11B #define VBE_VESA_MODE_1600X1200X8 0x11C #define VBE_VESA_MODE_1600X1200X1555 0x11D #define VBE_VESA_MODE_1600X1200X565 0x11E #define VBE_VESA_MODE_1600X1200X888 0x11F // BOCHS/PLEX86 'own' mode numbers #define VBE_OWN_MODE_320X200X8888 0x140 #define VBE_OWN_MODE_640X400X8888 0x141 #define VBE_OWN_MODE_640X480X8888 0x142 #define VBE_OWN_MODE_800X600X8888 0x143 #define VBE_OWN_MODE_1024X768X8888 0x144 #define VBE_OWN_MODE_1280X1024X8888 0x145 #define VBE_OWN_MODE_320X200X8 0x146 #define VBE_OWN_MODE_1600X1200X8888 0x147 #define VBE_OWN_MODE_1152X864X8 0x148 #define VBE_OWN_MODE_1152X864X1555 0x149 #define VBE_OWN_MODE_1152X864X565 0x14a #define VBE_OWN_MODE_1152X864X888 0x14b #define VBE_OWN_MODE_1152X864X8888 0x14c #define VBE_VESA_MODE_END_OF_LIST 0xFFFF // Capabilities #define VBE_CAPABILITY_8BIT_DAC 0x0001 #define VBE_CAPABILITY_NOT_VGA_COMPATIBLE 0x0002 #define VBE_CAPABILITY_RAMDAC_USE_BLANK_BIT 0x0004 #define VBE_CAPABILITY_STEREOSCOPIC_SUPPORT 0x0008 #define VBE_CAPABILITY_STEREO_VIA_VESA_EVC 0x0010 // Mode Attributes #define VBE_MODE_ATTRIBUTE_SUPPORTED 0x0001 #define VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE 0x0002 #define VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT 0x0004 #define VBE_MODE_ATTRIBUTE_COLOR_MODE 0x0008 #define VBE_MODE_ATTRIBUTE_GRAPHICS_MODE 0x0010 #define VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE 0x0020 #define VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW 0x0040 #define VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE 0x0080 #define VBE_MODE_ATTRIBUTE_DOUBLE_SCAN_MODE 0x0100 #define VBE_MODE_ATTRIBUTE_INTERLACE_MODE 0x0200 #define VBE_MODE_ATTRIBUTE_HARDWARE_TRIPLE_BUFFER 0x0400 #define VBE_MODE_ATTRIBUTE_HARDWARE_STEREOSCOPIC_DISPLAY 0x0800 #define VBE_MODE_ATTRIBUTE_DUAL_DISPLAY_START_ADDRESS 0x1000 #define VBE_MODE_ATTTRIBUTE_LFB_ONLY ( VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW | VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE ) // Window attributes #define VBE_WINDOW_ATTRIBUTE_RELOCATABLE 0x01 #define VBE_WINDOW_ATTRIBUTE_READABLE 0x02 #define VBE_WINDOW_ATTRIBUTE_WRITEABLE 0x04 // Memory model #define VBE_MEMORYMODEL_TEXT_MODE 0x00 #define VBE_MEMORYMODEL_CGA_GRAPHICS 0x01 #define VBE_MEMORYMODEL_HERCULES_GRAPHICS 0x02 #define VBE_MEMORYMODEL_PLANAR 0x03 #define VBE_MEMORYMODEL_PACKED_PIXEL 0x04 #define VBE_MEMORYMODEL_NON_CHAIN_4_256 0x05 #define VBE_MEMORYMODEL_DIRECT_COLOR 0x06 #define VBE_MEMORYMODEL_YUV 0x07 // DirectColorModeInfo #define VBE_DIRECTCOLOR_COLOR_RAMP_PROGRAMMABLE 0x01 #define VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE 0x02 // GUEST <-> HOST Communication API // FIXME: either dynamicly ask host for this or put somewhere high in physical memory // like 0xE0000000 #define VBE_DISPI_BANK_ADDRESS 0xA0000 #define VBE_DISPI_BANK_SIZE_KB 64 #define VBE_DISPI_MAX_XRES 2560 #define VBE_DISPI_MAX_YRES 1600 #define VBE_DISPI_IOPORT_INDEX 0x01CE #define VBE_DISPI_IOPORT_DATA 0x01CF #define VBE_DISPI_INDEX_ID 0x0 #define VBE_DISPI_INDEX_XRES 0x1 #define VBE_DISPI_INDEX_YRES 0x2 #define VBE_DISPI_INDEX_BPP 0x3 #define VBE_DISPI_INDEX_ENABLE 0x4 #define VBE_DISPI_INDEX_BANK 0x5 #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 #define VBE_DISPI_INDEX_X_OFFSET 0x8 #define VBE_DISPI_INDEX_Y_OFFSET 0x9 #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa #define VBE_DISPI_ID0 0xB0C0 #define VBE_DISPI_ID1 0xB0C1 #define VBE_DISPI_ID2 0xB0C2 #define VBE_DISPI_ID3 0xB0C3 #define VBE_DISPI_ID4 0xB0C4 #define VBE_DISPI_ID5 0xB0C5 #define VBE_DISPI_DISABLED 0x00 #define VBE_DISPI_ENABLED 0x01 #define VBE_DISPI_GETCAPS 0x02 #define VBE_DISPI_8BIT_DAC 0x20 #define VBE_DISPI_LFB_ENABLED 0x40 #define VBE_DISPI_NOCLEARMEM 0x80 #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 #endif vgabios-0.7a/Makefile0000644000175000017500000000474211611334006014473 0ustar guillemguillemSHELL = /bin/sh CC = gcc CFLAGS = -g -O2 -Wall -Wstrict-prototypes LDFLAGS = GCC = gcc BCC = bcc AS86 = as86 RELEASE = `pwd | sed "s-.*/--"` RELDATE = `date '+%d %b %Y'` RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" all: bios cirrus-bios bios: vgabios.bin vgabios.debug.bin cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin clean: /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \ temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak dist-clean: clean # source files VGA_FILES := vgabios.c vgabios.h vgafonts.h vgatables.h VBE_FILES := vbe.h vbe.c vbetables.h # build flags vgabios.bin : VGAFLAGS := -DVBE -DPCIBIOS vgabios.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DDEBUG vgabios-cirrus.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG # dist names vgabios.bin : DISTNAME := VGABIOS-lgpl-latest.bin vgabios.debug.bin : DISTNAME := VGABIOS-lgpl-latest.debug.bin vgabios-cirrus.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.bin vgabios-cirrus.debug.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.debug.bin # dependencies vgabios.bin : $(VGA_FILES) $(VBE_FILES) biossums vgabios.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums vgabios-cirrus.bin : $(VGA_FILES) clext.c biossums vgabios-cirrus.debug.bin : $(VGA_FILES) clext.c biossums # build rule %.bin: $(GCC) -E -P vgabios.c $(VGABIOS_VERS) $(VGAFLAGS) $(VGABIOS_DATE) > _$*_.c $(BCC) -o $*.s -C-c -D__i86__ -S -0 _$*_.c sed -e 's/^\.text//' -e 's/^\.data//' $*.s > _$*_.s $(AS86) _$*_.s -b $*.bin -u -w- -g -0 -j -O -l $*.txt rm -f _$*_.s _$*_.c $*.s mv $*.bin $(DISTNAME) ./biossums $(DISTNAME) ls -l $(DISTNAME) release: VGABIOS_VERS=\"-DVGABIOS_VERS=\\\"$(RELVERS)\\\"\" make bios cirrus-bios /bin/rm -f *.o *.s *.ld86 \ temp.awk.* vgabios.*.orig _vgabios_.*.c core *.bak .#* cp VGABIOS-lgpl-latest.bin ../$(RELEASE).bin cp VGABIOS-lgpl-latest.debug.bin ../$(RELEASE).debug.bin cp VGABIOS-lgpl-latest.cirrus.bin ../$(RELEASE).cirrus.bin cp VGABIOS-lgpl-latest.cirrus.debug.bin ../$(RELEASE).cirrus.debug.bin tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/ biossums: biossums.c $(CC) -o biossums biossums.c vbetables-gen: vbetables-gen.c $(CC) -o vbetables-gen vbetables-gen.c vbetables.h: vbetables-gen ./vbetables-gen > $@ vgabios-0.7a/vgatables.h0000644000175000017500000006423510411214472015160 0ustar guillemguillem/* * * BIOS Memory * */ #define BIOSMEM_SEG 0x40 #define BIOSMEM_INITIAL_MODE 0x10 #define BIOSMEM_CURRENT_MODE 0x49 #define BIOSMEM_NB_COLS 0x4A #define BIOSMEM_PAGE_SIZE 0x4C #define BIOSMEM_CURRENT_START 0x4E #define BIOSMEM_CURSOR_POS 0x50 #define BIOSMEM_CURSOR_TYPE 0x60 #define BIOSMEM_CURRENT_PAGE 0x62 #define BIOSMEM_CRTC_ADDRESS 0x63 #define BIOSMEM_CURRENT_MSR 0x65 #define BIOSMEM_CURRENT_PAL 0x66 #define BIOSMEM_NB_ROWS 0x84 #define BIOSMEM_CHAR_HEIGHT 0x85 #define BIOSMEM_VIDEO_CTL 0x87 #define BIOSMEM_SWITCHES 0x88 #define BIOSMEM_MODESET_CTL 0x89 #define BIOSMEM_DCC_INDEX 0x8A #define BIOSMEM_VS_POINTER 0xA8 #define BIOSMEM_VBE_FLAG 0xB9 #define BIOSMEM_VBE_MODE 0xBA /* * * VGA registers * */ #define VGAREG_ACTL_ADDRESS 0x3c0 #define VGAREG_ACTL_WRITE_DATA 0x3c0 #define VGAREG_ACTL_READ_DATA 0x3c1 #define VGAREG_INPUT_STATUS 0x3c2 #define VGAREG_WRITE_MISC_OUTPUT 0x3c2 #define VGAREG_VIDEO_ENABLE 0x3c3 #define VGAREG_SEQU_ADDRESS 0x3c4 #define VGAREG_SEQU_DATA 0x3c5 #define VGAREG_PEL_MASK 0x3c6 #define VGAREG_DAC_STATE 0x3c7 #define VGAREG_DAC_READ_ADDRESS 0x3c7 #define VGAREG_DAC_WRITE_ADDRESS 0x3c8 #define VGAREG_DAC_DATA 0x3c9 #define VGAREG_READ_FEATURE_CTL 0x3ca #define VGAREG_READ_MISC_OUTPUT 0x3cc #define VGAREG_GRDC_ADDRESS 0x3ce #define VGAREG_GRDC_DATA 0x3cf #define VGAREG_MDA_CRTC_ADDRESS 0x3b4 #define VGAREG_MDA_CRTC_DATA 0x3b5 #define VGAREG_VGA_CRTC_ADDRESS 0x3d4 #define VGAREG_VGA_CRTC_DATA 0x3d5 #define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba #define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da #define VGAREG_ACTL_RESET 0x3da #define VGAREG_MDA_MODECTL 0x3b8 #define VGAREG_CGA_MODECTL 0x3d8 #define VGAREG_CGA_PALETTE 0x3d9 /* Video memory */ #define VGAMEM_GRAPH 0xA000 #define VGAMEM_CTEXT 0xB800 #define VGAMEM_MTEXT 0xB000 /* * * Tables of default values for each mode * */ #define MODE_MAX 15 #define TEXT 0x00 #define GRAPH 0x01 #define CTEXT 0x00 #define MTEXT 0x01 #define CGA 0x02 #define PLANAR1 0x03 #define PLANAR4 0x04 #define LINEAR8 0x05 // for SVGA #define LINEAR15 0x10 #define LINEAR16 0x11 #define LINEAR24 0x12 #define LINEAR32 0x13 typedef struct {Bit8u svgamode; Bit8u class; /* TEXT, GRAPH */ Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ Bit8u pixbits; Bit16u sstart; Bit8u pelmask; Bit8u dacmodel; /* 0 1 2 3 */ } VGAMODES; static VGAMODES vga_modes[MODE_MAX+1]= {//mode class model bits sstart pelm dac {0x00, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, {0x01, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, {0x02, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, {0x03, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, {0x04, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, {0x05, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, {0x06, GRAPH, CGA, 1, 0xB800, 0xFF, 0x01}, {0x07, TEXT, MTEXT, 4, 0xB000, 0xFF, 0x00}, {0x0D, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, {0x0E, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, {0x0F, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x00}, {0x10, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, {0x11, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x02}, {0x12, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, {0x13, GRAPH, LINEAR8, 8, 0xA000, 0xFF, 0x03}, {0x6A, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02} }; /* convert index in vga_modes[] to index in video_param_table[] */ static Bit8u line_to_vpti[MODE_MAX+1]={ 0x17, 0x17, 0x18, 0x18, 0x04, 0x05, 0x06, 0x07, 0x0d, 0x0e, 0x11, 0x12, 0x1a, 0x1b, 0x1c, 0x1d, }; /* Default Palette */ #define DAC_MAX_MODEL 3 static Bit8u dac_regs[DAC_MAX_MODEL+1]= {0x3f,0x3f,0x3f,0xff}; /* standard BIOS Video Parameter Table */ typedef struct { Bit8u twidth; Bit8u theightm1; Bit8u cheight; Bit8u slength_l; Bit8u slength_h; Bit8u sequ_regs[4]; Bit8u miscreg; Bit8u crtc_regs[25]; Bit8u actl_regs[20]; Bit8u grdc_regs[9]; } VideoParamTableEntry; static VideoParamTableEntry video_param_table[30] = { { /* index=0x00 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x01 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x02 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x03 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x04 vga mode 0x04 */ 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ 0x63, /* miscreg */ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, /* crtc_regs */ 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x05 vga mode 0x05 */ 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ 0x63, /* miscreg */ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, 0xff, /* crtc_regs */ 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x06 vga mode 0x06 */ 80, 24, 8, 0x00, 0x10, /* tw, th-1, ch, slength */ 0x01, 0x01, 0x00, 0x06, /* sequ_regs */ 0x63, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, 0xff, /* crtc_regs */ 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x07 vga mode 0x07 */ 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ 0x66, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, /* crtc_regs */ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x08 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x09 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x0a no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x0b no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x0c no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x0d vga mode 0x0d */ 40, 24, 8, 0x00, 0x20, /* tw, th-1, ch, slength */ 0x09, 0x0f, 0x00, 0x06, /* sequ_regs */ 0x63, /* miscreg */ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x0e vga mode 0x0e */ 80, 24, 8, 0x00, 0x40, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0x63, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x0f no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x10 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x11 vga mode 0x0f */ 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0xa3, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x12 vga mode 0x10 */ 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0xa3, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x13 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x14 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x15 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x16 no mode defined */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, { /* index=0x17 vga mode 0x01 */ 40, 24, 16, 0x00, 0x08, /* tw, th-1, ch, slength */ 0x08, 0x03, 0x00, 0x02, /* sequ_regs */ 0x67, /* miscreg */ 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x18 vga mode 0x03 */ 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ 0x67, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x19 vga mode 0x07 */ 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ 0x66, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, 0xff, /* crtc_regs */ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x1a vga mode 0x11 */ 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0xe3, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x1b vga mode 0x12 */ 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0xe3, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x1c vga mode 0x13 */ 40, 24, 8, 0x00, 0x00, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x0e, /* sequ_regs */ 0x63, /* miscreg */ 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x41, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, /* grdc_regs */ }, { /* index=0x1d vga mode 0x6a */ 100, 36, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ 0xe3, /* miscreg */ 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3, 0xff, /* crtc_regs */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ }, }; /* Mono */ static Bit8u palette0[63+1][3]= { 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f }; static Bit8u palette1[63+1][3]= { 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f }; static Bit8u palette2[63+1][3]= { 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f }; static Bit8u palette3[256][3]= { 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 }; static Bit8u static_functionality[0x10]= { /* 0 */ 0xff, // All modes supported #1 /* 1 */ 0xe0, // All modes supported #2 /* 2 */ 0x0f, // All modes supported #3 /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved /* 7 */ 0x07, // 200, 350, 400 scan lines /* 8 */ 0x02, // mamimum number of visible charsets in text mode /* 9 */ 0x08, // total number of charset blocks in text mode /* a */ 0xe7, // Change to add new functions /* b */ 0x0c, // Change to add new functions /* c */ 0x00, // reserved /* d */ 0x00, // reserved /* e */ 0x00, // Change to add new functions /* f */ 0x00 // reserved }; vgabios-0.7a/README0000644000175000017500000002063511653242173013723 0ustar guillemguillemPlex86/Bochs VGABios -------------------- The goal of this project is to have a LGPL'd Video Bios in plex86, Bochs and qemu. This VGA Bios is very specific to the emulated VGA card. It is NOT meant to drive a physical vga card. Cirrus SVGA extension --------------------- The Cirrus SVGA extension is designed for the Cirrus emulation in Bochs and qemu. The initial patch for the Cirrus extension has been written by Makoto Suzuki (suzu). Install ------- To compile the VGA Bios you will need : - gcc - bcc - as86 - ld86 Untar the archive, and type make. You should get a "VGABIOS-lgpl-latest.bin" file. Alternatively, you can use the binary file "VGABIOS-lgpl-latest.bin", i have compiled for you. Edit your plex86/bochs conf file, and modify the load-rom command in the VGA BIOS section, to point to the new vgabios image file. Debugging --------- You can get a very basic debugging system: messages printed by the vgabios. You have to register the "unmapped" device driver in plex86 or bochs, and make sure it grabs port 0xfff0. Comment the #undef DEBUG at the beginning of vgabios.c. You can then use the "printf" function in the bios. Testing ------- Look at the "testvga.c" file in the archive. This is a minimal Turbo C 2.0 source file that calls a few int10 functions. Feel free to modify it to suit your needs. Copyright and License --------------------- This program has been written by Christophe Bothamy It is protected by the GNU Lesser Public License, which you should have received a copy of along with this package. Reverse Engineering ------------------- The VGA Bios has been written without reverse-engineering any existing Bios. Acknowledgment -------------- The source code contains code ripped from rombios.c of plex86, written by Kevin Lawton The source code contains fonts from fntcol16.zip (c) by Joseph Gil avalable at : ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip These fonts are public domain The source code is based on information taken from : - Kevin Lawton's vga card emulation for bochs/plex86 - Ralf Brown's interrupts list avalaible at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ - Michael Abrash's Graphics Programming Black Book - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex - DOSEMU 1.0.1 source code for several tables values and formulas Feedback -------- Please report any bugs, comments, patches for this VGA Bios to info@vruppert.de You can find the latest release at : http://www.nongnu.org/vgabios/ For any information on bochs, visit the website http://bochs.sourceforge.net/ For any information on qemu, visit the website http://fabrice.bellard.free.fr/qemu/ History ------- vgabios-0.7a : Oct 30 2011 - Volker . added HDTV resolutions (patch by Tristan Schmelcher) . added PCI ROM support to the VBE-specific images . implemented vgabios functions with AX=0x112x (patch by Hugo Mercier) . fixed DAC palette in 8 bpp VBE and Cirrus modes (using the same palette as VGA mode 0x13) . Makefile cleanup (patch by Gerd Hoffmann) vgabios-0.6c : Apr 08 2009 - Volker . added DPMS support to cirrus vgabios (patch from Gleb Natapov) . use VBE LFB address from PCI base address if present . added support for a lot more non-standard VBE modes (e.g. widescreen modes) . minor bugfixes vgabios-0.6b : May 30 2008 - Volker . added PCI data structure for the Cirrus VGABIOS images . minor bugfixes in biossums utility, VBE support and makefile vgabios-0.6a : Aug 19 2006 - Volker . added minimal support for the video parameter table (VPT) . Cirrus SVGA now supports the "no clear" bit in Cirrus and VESA mode . Bochs VBE protected mode interface improved . save/restore video state support for Bochs VBE and standard VGA added . generate vbetables.h dynamicly . VBE video memory increased to 8 MB (VBE dispi ID changed to B0C4) . lots of 4bpp VBE fixes (all 4bpp VBE modes now enabled) . VGA compatible setup for VBE modes added vgabios-0.5d : Dec 29 2005 - Volker . Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) . biossums utility now supports VGABIOS sizes up to 64 kBytes . VGA mode 0x11: all color planes must be enabled in this 2-color VGA mode vgabios-0.5c : Jul 07 2005 - Volker . BIOS configuration word usually reports initial mode 80x25 color text . vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the cursor row value vgabios-0.5b : May 24 2005 - Volker . fixed return value for the default case in the VBE section (non-debug mode) . removed unused stuff vgabios-0.5a : Mar 07 2005 - Volker . Cirrus SVGA extension (initial patches from Makoto Suzuki, improvements from Fabrice Bellard) . vgabios image size is now exactly 32k with a checksum . a lot of vgabios and vbe functions rewritten in assembler . dynamicly generated VBE mode info list . write character function for CGA and LINEAR8 modes . read/write graphics pixel for some graphics modes . text scroll feature for some graphics modes . VBE 8-bit DAC support vgabios-0.4c : Nov 06 2003 - Christophe . fix font problem on initial screen of NT4 Loader vgabios-0.4b : Nov 04 2003 - Volker . fix offset of character tables . optimizations of CRT controller accesses . VBE i/o registers changed to 0x01CE/CF (suggestion from Daniel Gimpelevich) . "noclear" flag stored in BIOS area . fix character height returned by get_font_info function vgabios-0.4a : Aug 17 2003 - Volker . VBE mode search rewritten (VBE modes with LFB bit removed) . many bugfixes and optimizations . write character function implemented for graphics modes . support for 15bpp, 16bpp, 24bpp and 32bpp VBE modes added . SVGA mode 0x6A added . VBE modes 0x102, 0x117, 0x118 and 0x142 (Bochs specific) vgabios-0.3b : Nov 23 2002 - Christophe . added lfb-mode numbers (patch from mathis) . updated the Makefile . removed display of copyrights. . changed the Copyright string to "LGPL VGABios developers" - Volker . set the cursor shape depending on the current font height . clear BL before calling int 0x10 function 0x1103 in vgabios_init_func . added some text font functions - Jeroen . Forced to new DISPI (0xb0c1) interface (requires latest bochs vbe code) . Added multibuffering support . Added new DISPI interface for: virt width, height, x offset, y offset . Added LFB modes (to be used with the vbe-lfb patch in bochs) see VBE_HAVE_LFB in vbe.c (currently default enabled) . updated TODO & docs for changes after bochs 1.4 vgabios-0.3a : Mar 10 2002 - Christophe . Fixed bug in function ah=13 - Jeroen . updated vbebios implementation to new api . added vbe_display_api documentation . added 640x400x8, 640x480x8, 800x600x8, 1024x768 (>640x480 needs a special bochs patch atm) . added 320x200x8 vbe support (uses the standard 320x200x8 vga mode to display, this allows for testing & having something on screen as well, at least until bochs host side display is up & running) . adding lfbprof (vbe) testprogram (+some small fixes to it) . merging with vbebios 0.2 vgabios-0.2b : Nov 19 2001 - Christophe . Fixed bug in function ah=13 vgabios-0.2a : Nov 09 2001 - Christophe . Included bugfix from techt@pikeonline.net about grayscale summing . Added the "IBM" string at org 0x1e as Bart Oldeman suggested . Fixed DS and ES that where inverted in the int10 parameters list! . The following have been implemented : - function ax=1a00, ax=1a01, ah=1b - function ax=1130 . Added debug messages for unimplemented/unknown functions Must be compiled with DEBUG defined. The output is trapped by the unknown-ioport driver of plex/bochs (port 0xfff0 is used) vgabios-0.1a : May 8 2001 - Christophe . First release. The work has been focused only on text mode. . The following have been implemented : - inits - int 10 handler - functions ah=00, ah=01, ah=02, ah=03, ah=05, ah=06, ah=07, ah=08 ah=09, ah=0a, ah=0e, ah=0f, ax=1000, ax=1001, ax=1002, ax=1003 ax=1007, ax=1008, ax=1009, ax=1010, ax=1012, ax=1013, ax=1015 ax=1017, ax=1018, ax=1019, ax=101a, ax=101b, ah=12 bl=10, ah=12 bl=30, ah=12 bl=31, ah=12 bl=32, ah=12 bl=33, ah=12 bl=34 ah=13 vgabios-0.7a/vgafonts.h0000644000175000017500000016414007434154024015042 0ustar guillemguillem/* * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip * The package is (c) by Joseph Gil * The individual fonts are public domain */ static Bit8u vgafont8[256*8]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static Bit8u vgafont14[256*14]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static Bit8u vgafont16[256*16]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static Bit8u vgafont14alt[1]={0x00}; static Bit8u vgafont16alt[1]={0x00}; vgabios-0.7a/clext.c0000644000175000017500000007417311551616121014327 0ustar guillemguillem// // QEMU Cirrus CLGD 54xx VGABIOS Extension. // // Copyright (c) 2004 Makoto Suzuki (suzu) // // 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 // //#define CIRRUS_VESA3_PMINFO #ifdef VBE #undef CIRRUS_VESA3_PMINFO #endif #define PM_BIOSMEM_CURRENT_MODE 0x449 #define PM_BIOSMEM_CRTC_ADDRESS 0x463 #define PM_BIOSMEM_VBE_MODE 0x4BA typedef struct { /* + 0 */ unsigned short mode; unsigned short width; unsigned short height; unsigned short depth; /* + 8 */ unsigned short hidden_dac; /* 0x3c6 */ unsigned short *seq; /* 0x3c4 */ unsigned short *graph; /* 0x3ce */ unsigned short *crtc; /* 0x3d4 */ /* +16 */ unsigned char bitsperpixel; unsigned char vesacolortype; unsigned char vesaredmask; unsigned char vesaredpos; unsigned char vesagreenmask; unsigned char vesagreenpos; unsigned char vesabluemask; unsigned char vesabluepos; /* +24 */ unsigned char vesareservedmask; unsigned char vesareservedpos; } cirrus_mode_t; #define CIRRUS_MODE_SIZE 26 /* For VESA BIOS 3.0 */ #define CIRRUS_PM16INFO_SIZE 20 /* VGA */ unsigned short cseq_vga[] = {0x0007,0xffff}; unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff}; unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff}; /* extensions */ unsigned short cgraph_svgacolor[] = { 0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, 0x0009,0x000a,0x000b, 0xffff }; /* 640x480x8 */ unsigned short cseq_640x480x8[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 0x580b,0x580c,0x580d,0x580e, 0x0412,0x0013,0x2017, 0x331b,0x331c,0x331d,0x331e, 0xffff }; unsigned short ccrtc_640x480x8[] = { 0x2c11, 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 0x4009,0x000c,0x000d, 0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 640x480x16 */ unsigned short cseq_640x480x16[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 0x580b,0x580c,0x580d,0x580e, 0x0412,0x0013,0x2017, 0x331b,0x331c,0x331d,0x331e, 0xffff }; unsigned short ccrtc_640x480x16[] = { 0x2c11, 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 0x4009,0x000c,0x000d, 0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 640x480x24 */ unsigned short cseq_640x480x24[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 0x580b,0x580c,0x580d,0x580e, 0x0412,0x0013,0x2017, 0x331b,0x331c,0x331d,0x331e, 0xffff }; unsigned short ccrtc_640x480x24[] = { 0x2c11, 0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, 0x4009,0x000c,0x000d, 0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, 0x001a,0x321b,0x001d, 0xffff }; /* 800x600x8 */ unsigned short cseq_800x600x8[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 0x230b,0x230c,0x230d,0x230e, 0x0412,0x0013,0x2017, 0x141b,0x141c,0x141d,0x141e, 0xffff }; unsigned short ccrtc_800x600x8[] = { 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 0x6009,0x000c,0x000d, 0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 800x600x16 */ unsigned short cseq_800x600x16[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 0x230b,0x230c,0x230d,0x230e, 0x0412,0x0013,0x2017, 0x141b,0x141c,0x141d,0x141e, 0xffff }; unsigned short ccrtc_800x600x16[] = { 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 0x6009,0x000c,0x000d, 0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 800x600x24 */ unsigned short cseq_800x600x24[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 0x230b,0x230c,0x230d,0x230e, 0x0412,0x0013,0x2017, 0x141b,0x141c,0x141d,0x141e, 0xffff }; unsigned short ccrtc_800x600x24[] = { 0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, 0x6009,0x000c,0x000d, 0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18, 0x001a,0x321b,0x001d, 0xffff }; /* 1024x768x8 */ unsigned short cseq_1024x768x8[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1024x768x8[] = { 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 0x6009,0x000c,0x000d, 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 1024x768x16 */ unsigned short cseq_1024x768x16[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1024x768x16[] = { 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 0x6009,0x000c,0x000d, 0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x321b,0x001d, 0xffff }; /* 1024x768x24 */ unsigned short cseq_1024x768x24[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1024x768x24[] = { 0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, 0x6009,0x000c,0x000d, 0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x321b,0x001d, 0xffff }; /* 1280x1024x8 */ unsigned short cseq_1280x1024x8[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1280x1024x8[] = { 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 0x6009,0x000c,0x000d, 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; /* 1280x1024x16 */ unsigned short cseq_1280x1024x16[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1280x1024x16[] = { 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 0x6009,0x000c,0x000d, 0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x321b,0x001d, 0xffff }; /* 1600x1200x8 */ unsigned short cseq_1600x1200x8[] = { 0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, 0x760b,0x760c,0x760d,0x760e, 0x0412,0x0013,0x2017, 0x341b,0x341c,0x341d,0x341e, 0xffff }; unsigned short ccrtc_1600x1200x8[] = { 0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, 0x6009,0x000c,0x000d, 0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, 0x001a,0x221b,0x001d, 0xffff }; cirrus_mode_t cirrus_modes[] = { {0x5f,640,480,8,0x00, cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, 4,0,0,0,0,0,0,0,0}, {0x64,640,480,16,0xe1, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 6,5,11,6,5,5,0,0,0}, {0x66,640,480,15,0xf0, cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, 6,5,10,5,5,5,0,1,15}, {0x71,640,480,24,0xe5, cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, 6,8,16,8,8,8,0,0,0}, {0x5c,800,600,8,0x00, cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, 4,0,0,0,0,0,0,0,0}, {0x65,800,600,16,0xe1, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 6,5,11,6,5,5,0,0,0}, {0x67,800,600,15,0xf0, cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, 6,5,10,5,5,5,0,1,15}, {0x60,1024,768,8,0x00, cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, 4,0,0,0,0,0,0,0,0}, {0x74,1024,768,16,0xe1, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 6,5,11,6,5,5,0,0,0}, {0x68,1024,768,15,0xf0, cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, 6,5,10,5,5,5,0,1,15}, {0x78,800,600,24,0xe5, cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, 6,8,16,8,8,8,0,0,0}, {0x79,1024,768,24,0xe5, cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, 6,8,16,8,8,8,0,0,0}, {0x6d,1280,1024,8,0x00, cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, 4,0,0,0,0,0,0,0,0}, {0x69,1280,1024,15,0xf0, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 6,5,10,5,5,5,0,1,15}, {0x75,1280,1024,16,0xe1, cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, 6,5,11,6,5,5,0,0,0}, {0x7b,1600,1200,8,0x00, cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, 4,0,0,0,0,0,0,0,0}, {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, 0xff,0,0,0,0,0,0,0,0}, {0xff,0,0,0,0,0,0,0,0, 0xff,0,0,0,0,0,0,0,0}, }; unsigned char cirrus_id_table[] = { // 5430 0xA0, 0x32, // 5446 0xB8, 0x39, 0xff, 0xff }; unsigned short cirrus_vesa_modelist[] = { // 640x480x8 0x101, 0x5f, // 640x480x15 0x110, 0x66, // 640x480x16 0x111, 0x64, // 640x480x24 0x112, 0x71, // 800x600x8 0x103, 0x5c, // 800x600x15 0x113, 0x67, // 800x600x16 0x114, 0x65, // 800x600x24 0x115, 0x78, // 1024x768x8 0x105, 0x60, // 1024x768x15 0x116, 0x68, // 1024x768x16 0x117, 0x74, // 1024x768x24 0x118, 0x79, // 1280x1024x8 0x107, 0x6d, // 1280x1024x15 0x119, 0x69, // 1280x1024x16 0x11a, 0x75, // invalid 0xffff,0xffff }; ASM_START cirrus_installed: .ascii "cirrus-compatible VGA is detected" .byte 0x0d,0x0a .byte 0x0d,0x0a,0x00 cirrus_not_installed: .ascii "cirrus-compatible VGA is not detected" .byte 0x0d,0x0a .byte 0x0d,0x0a,0x00 cirrus_vesa_vendorname: cirrus_vesa_productname: cirrus_vesa_oemname: .ascii "VGABIOS Cirrus extension" .byte 0 cirrus_vesa_productrevision: .ascii "1.0" .byte 0 cirrus_init: call cirrus_check jnz no_cirrus SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) mov al, #0x0f ; memory setup mov dx, #0x3C4 out dx, al inc dx in al, dx and al, #0x18 mov ah, al mov al, #0x0a dec dx out dx, ax mov ax, #0x0007 ; set vga mode out dx, ax mov ax, #0x0431 ; reset bitblt mov dx, #0x3CE out dx, ax mov ax, #0x0031 out dx, ax no_cirrus: ret cirrus_display_info: push ds push si push cs pop ds call cirrus_check mov si, #cirrus_not_installed jnz cirrus_msgnotinstalled mov si, #cirrus_installed cirrus_msgnotinstalled: call _display_string pop si pop ds ret cirrus_check: push ax push dx mov ax, #0x9206 mov dx, #0x3C4 out dx, ax inc dx in al, dx cmp al, #0x12 pop dx pop ax ret cirrus_int10_handler: pushf push bp cmp ah, #0x00 ;; set video mode jz cirrus_set_video_mode cmp ah, #0x12 ;; cirrus extension jz cirrus_extbios cmp ah, #0x4F ;; VESA extension jz cirrus_vesa cirrus_unhandled: pop bp popf jmp vgabios_int10_handler cirrus_return: #ifdef CIRRUS_DEBUG call cirrus_debug_dump #endif pop bp popf iret cirrus_set_video_mode: #ifdef CIRRUS_DEBUG call cirrus_debug_dump #endif push si push ax push bx push ds #ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov si, [cirrus_vesa_sel0000_data] #else xor si, si #endif mov ds, si xor bx, bx mov [PM_BIOSMEM_VBE_MODE], bx pop ds pop bx call cirrus_get_modeentry jnc cirrus_set_video_mode_extended mov al, #0xfe call cirrus_get_modeentry_nomask call cirrus_switch_mode pop ax pop si jmp cirrus_unhandled cirrus_extbios: #ifdef CIRRUS_DEBUG call cirrus_debug_dump #endif cmp bl, #0x80 jb cirrus_unhandled cmp bl, #0xAF ja cirrus_unhandled push bx and bx, #0x7F shl bx, 1 db 0x2e ;; cs: mov bp, cirrus_extbios_handlers[bx] pop bx push #cirrus_return push bp ret cirrus_vesa: #ifdef CIRRUS_DEBUG call cirrus_debug_dump #endif cmp al, #0x10 ja cirrus_vesa_not_handled push bx xor bx, bx mov bl, al shl bx, 1 db 0x2e ;; cs: mov bp, cirrus_vesa_handlers[bx] pop bx push #cirrus_return push bp ret cirrus_vesa_not_handled: mov ax, #0x014F ;; not implemented jmp cirrus_return #ifdef CIRRUS_DEBUG cirrus_debug_dump: push es push ds pusha push cs pop ds call _cirrus_debugmsg popa pop ds pop es ret #endif cirrus_set_video_mode_extended: call cirrus_switch_mode pop ax ;; mode test al, #0x80 jnz cirrus_set_video_mode_extended_1 push ax mov ax, #0xffff ; set to 0xff to keep win 2K happy call cirrus_clear_vram pop ax cirrus_set_video_mode_extended_1: and al, #0x7f push ds #ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov si, [cirrus_vesa_sel0000_data] #else xor si, si #endif mov ds, si mov [PM_BIOSMEM_CURRENT_MODE], al pop ds mov al, #0x20 pop si jmp cirrus_return cirrus_vesa_pmbios_init: retf cirrus_vesa_pmbios_entry: pushf push bp cmp ah, #0x4F jnz cirrus_vesa_pmbios_unimplemented cmp al, #0x0F ja cirrus_vesa_pmbios_unimplemented push bx xor bx, bx mov bl, al shl bx, 1 db 0x2e ;; cs: mov bp, cirrus_vesa_handlers[bx] pop bx push #cirrus_vesa_pmbios_return push bp ret cirrus_vesa_pmbios_unimplemented: mov ax, #0x014F cirrus_vesa_pmbios_return: pop bp popf retf ; in si:mode table cirrus_switch_mode: push ds push bx push dx push cs pop ds mov bx, [si+10] ;; seq mov dx, #0x3c4 mov ax, #0x1206 out dx, ax ;; Unlock cirrus special call cirrus_switch_mode_setregs mov bx, [si+12] ;; graph mov dx, #0x3ce call cirrus_switch_mode_setregs mov bx, [si+14] ;; crtc call cirrus_get_crtc call cirrus_switch_mode_setregs mov dx, #0x3c6 mov al, #0x00 out dx, al in al, dx in al, dx in al, dx in al, dx mov al, [si+8] ;; hidden dac out dx, al mov al, #0xff out dx, al mov al, #0x00 mov bl, [si+17] ;; memory model or bl, bl jz is_text_mode mov al, #0x01 cmp bl, #0x03 jnz is_text_mode or al, #0x40 is_text_mode: mov bl, #0x10 call biosfn_get_single_palette_reg and bh, #0xfe or bh, al call biosfn_set_single_palette_reg mov al, [si+6] ;; bpp cmp al, #0x08 jnz no_8bpp_mode mov al, #0x03 xor ah,ah push ax call _load_dac_palette inc sp inc sp no_8bpp_mode: pop dx pop bx pop ds ret cirrus_enable_16k_granularity: push ax push dx mov dx, #0x3ce mov al, #0x0b out dx, al inc dx in al, dx or al, #0x20 ;; enable 16k out dx, al pop dx pop ax ret cirrus_switch_mode_setregs: csms_1: mov ax, [bx] cmp ax, #0xffff jz csms_2 out dx, ax add bx, #0x2 jmp csms_1 csms_2: ret cirrus_extbios_80h: push dx call cirrus_get_crtc mov al, #0x27 out dx, al inc dx in al, dx mov bx, #_cirrus_id_table c80h_1: db 0x2e ;; cs: mov ah, [bx] cmp ah, al jz c80h_2 cmp ah, #0xff jz c80h_2 inc bx inc bx jmp c80h_1 c80h_2: db 0x2e ;; cs: mov al, 0x1[bx] pop dx mov ah, #0x00 xor bx, bx ret cirrus_extbios_81h: mov ax, #0x100 ;; XXX ret cirrus_extbios_82h: push dx call cirrus_get_crtc xor ax, ax mov al, #0x27 out dx, al inc dx in al, dx and al, #0x03 mov ah, #0xAF pop dx ret cirrus_extbios_85h: push cx push dx mov dx, #0x3C4 mov al, #0x0f ;; get DRAM band width out dx, al inc dx in al, dx ;; al = 4 << bandwidth mov cl, al shr cl, #0x03 and cl, #0x03 cmp cl, #0x03 je c85h2 mov al, #0x04 shl al, cl jmp c85h3 c85h2: ;; 4MB or 2MB and al, #0x80 mov al, #0x20 ;; 2 MB je c85h3 mov al, #0x40 ;; 4 MB c85h3: pop dx pop cx ret cirrus_extbios_9Ah: mov ax, #0x4060 mov cx, #0x1132 ret cirrus_extbios_A0h: call cirrus_get_modeentry mov ah, #0x01 sbb ah, #0x00 mov bx, cirrus_extbios_A0h_callback mov si, #0xffff mov di, bx mov ds, bx mov es, bx ret cirrus_extbios_A0h_callback: ;; fatal: not implemented yet cli hlt retf cirrus_extbios_A1h: mov bx, #0x0E00 ;; IBM 8512/8513, color ret cirrus_extbios_A2h: mov al, #0x07 ;; HSync 31.5 - 64.0 kHz ret cirrus_extbios_AEh: mov al, #0x01 ;; High Refresh 75Hz ret cirrus_extbios_unimplemented: ret cirrus_vesa_00h: push ds push si mov bp, di push es pop ds cld mov ax, [di] cmp ax, #0x4256 ;; VB jnz cv00_1 mov ax, [di+2] cmp ax, #0x3245 ;; E2 jnz cv00_1 ;; VBE2 lea di, 0x14[bp] mov ax, #0x0100 ;; soft ver. stosw mov ax, # cirrus_vesa_vendorname stosw mov ax, cs stosw mov ax, # cirrus_vesa_productname stosw mov ax, cs stosw mov ax, # cirrus_vesa_productrevision stosw mov ax, cs stosw cv00_1: mov di, bp mov ax, #0x4556 ;; VE stosw mov ax, #0x4153 ;; SA stosw mov ax, #0x0200 ;; v2.00 stosw mov ax, # cirrus_vesa_oemname stosw mov ax, cs stosw xor ax, ax ;; caps stosw stosw lea ax, 0x40[bp] stosw mov ax, es stosw call cirrus_extbios_85h ;; vram in 64k mov ah, #0x00 stosw push cs pop ds lea di, 0x40[bp] mov si, #_cirrus_vesa_modelist cv00_2: lodsw stosw add si, #2 cmp ax, #0xffff jnz cv00_2 mov ax, #0x004F mov di, bp pop si pop ds ret cirrus_vesa_01h: mov ax, cx and ax, #0x3fff call cirrus_vesamode_to_mode cmp ax, #0xffff jnz cirrus_vesa_01h_1 jmp cirrus_vesa_unimplemented cirrus_vesa_01h_1: push ds push si push cx push dx push bx mov bp, di cld push cs pop ds call cirrus_get_modeentry_nomask push di xor ax, ax mov cx, #0x80 rep stosw ;; clear buffer pop di mov ax, #0x003b ;; mode stosw mov ax, #0x0007 ;; attr stosw mov ax, #0x0010 ;; granularity =16K stosw mov ax, #0x0040 ;; size =64K stosw mov ax, #0xA000 ;; segment A stosw xor ax, ax ;; no segment B stosw mov ax, #cirrus_vesa_05h_farentry stosw mov ax, cs stosw call cirrus_get_line_offset_entry stosw ;; bytes per scan line mov ax, [si+2] ;; width stosw mov ax, [si+4] ;; height stosw mov ax, #0x08 stosb mov ax, #0x10 stosb mov al, #1 ;; count of planes stosb mov al, [si+6] ;; bpp stosb mov al, #0x1 ;; XXX number of banks stosb mov al, [si+17] stosb ;; memory model mov al, #0x0 ;; XXX size of bank in K stosb call cirrus_get_line_offset_entry mov bx, [si+4] mul bx ;; dx:ax=vramdisp or ax, ax jz cirrus_vesa_01h_3 inc dx cirrus_vesa_01h_3: call cirrus_extbios_85h ;; al=vram in 64k mov ah, #0x00 mov cx, dx xor dx, dx div cx dec ax stosb ;; number of image pages = vramtotal/vramdisp-1 mov al, #0x00 stosb ;; v1.2+ stuffs push si add si, #18 movsw movsw movsw movsw pop si mov ah, [si+16] mov al, #0x0 sub ah, #9 rcl al, #1 ; bit 0=palette flag stosb ;; direct screen mode info ;; v2.0+ stuffs ;; 32-bit LFB address xor ax, ax stosw mov ax, #0x1013 ;; vendor Cirrus call _pci_get_lfb_addr stosw or ax, ax jz cirrus_vesa_01h_4 push di mov di, bp db 0x26 ;; es: mov ax, [di] or ax, #0x0080 ;; mode bit 7:LFB stosw pop di cirrus_vesa_01h_4: xor ax, ax stosw ; reserved stosw ; reserved stosw ; reserved mov ax, #0x004F mov di, bp pop bx pop dx pop cx pop si pop ds test cx, #0x4000 ;; LFB flag jz cirrus_vesa_01h_5 push cx db 0x26 ;; es: mov cx, [di] cmp cx, #0x0080 ;; is LFB supported? jnz cirrus_vesa_01h_6 mov ax, #0x014F ;; error - no LFB cirrus_vesa_01h_6: pop cx cirrus_vesa_01h_5: ret cirrus_vesa_02h: ;; XXX support CRTC registers test bx, #0x3e00 jnz cirrus_vesa_02h_2 ;; unknown flags mov ax, bx and ax, #0x1ff ;; bit 8-0 mode cmp ax, #0x100 ;; legacy VGA mode jb cirrus_vesa_02h_legacy call cirrus_vesamode_to_mode cmp ax, #0xffff jnz cirrus_vesa_02h_1 cirrus_vesa_02h_2: jmp cirrus_vesa_unimplemented cirrus_vesa_02h_legacy: #ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: cmp byte ptr [cirrus_vesa_is_protected_mode], #0 jnz cirrus_vesa_02h_2 #endif // CIRRUS_VESA3_PMINFO int #0x10 mov ax, #0x004F ret cirrus_vesa_02h_1: push si push ax call cirrus_get_modeentry_nomask call cirrus_switch_mode test bx, #0x4000 ;; LFB jnz cirrus_vesa_02h_3 call cirrus_enable_16k_granularity cirrus_vesa_02h_3: test bx, #0x8000 ;; no clear jnz cirrus_vesa_02h_4 push ax xor ax,ax call cirrus_clear_vram pop ax cirrus_vesa_02h_4: pop ax push ds #ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov si, [cirrus_vesa_sel0000_data] #else xor si, si #endif mov ds, si mov [PM_BIOSMEM_CURRENT_MODE], al mov [PM_BIOSMEM_VBE_MODE], bx pop ds pop si mov ax, #0x004F ret cirrus_vesa_03h: push ds #ifdef CIRRUS_VESA3_PMINFO db 0x2e ;; cs: mov ax, [cirrus_vesa_sel0000_data] #else xor ax, ax #endif mov ds, ax mov bx, # PM_BIOSMEM_VBE_MODE mov ax, [bx] mov bx, ax test bx, bx jnz cirrus_vesa_03h_1 mov bx, # PM_BIOSMEM_CURRENT_MODE mov al, [bx] mov bl, al xor bh, bh cirrus_vesa_03h_1: mov ax, #0x004f pop ds ret cirrus_vesa_05h_farentry: call cirrus_vesa_05h retf cirrus_vesa_05h: cmp bl, #0x01 ja cirrus_vesa_05h_1 cmp bh, #0x00 jz cirrus_vesa_05h_setmempage cmp bh, #0x01 jz cirrus_vesa_05h_getmempage cirrus_vesa_05h_1: jmp cirrus_vesa_unimplemented cirrus_vesa_05h_setmempage: or dh, dh ; address must be < 0x100 jnz cirrus_vesa_05h_1 push dx mov al, bl ;; bl=bank number add al, #0x09 mov ah, dl ;; dx=window address in granularity mov dx, #0x3ce out dx, ax pop dx mov ax, #0x004F ret cirrus_vesa_05h_getmempage: mov al, bl ;; bl=bank number add al, #0x09 mov dx, #0x3ce out dx, al inc dx in al, dx xor dx, dx mov dl, al ;; dx=window address in granularity mov ax, #0x004F ret cirrus_vesa_06h: mov ax, cx cmp bl, #0x01 je cirrus_vesa_06h_3 cmp bl, #0x02 je cirrus_vesa_06h_2 jb cirrus_vesa_06h_1 mov ax, #0x0100 ret cirrus_vesa_06h_1: call cirrus_get_bpp_bytes mov bl, al xor bh, bh mov ax, cx mul bx cirrus_vesa_06h_2: call cirrus_set_line_offset cirrus_vesa_06h_3: call cirrus_get_bpp_bytes mov bl, al xor bh, bh xor dx, dx call cirrus_get_line_offset push ax div bx mov cx, ax pop bx call cirrus_extbios_85h ;; al=vram in 64k xor dx, dx mov dl, al xor ax, ax div bx mov dx, ax mov ax, #0x004f ret cirrus_vesa_07h: cmp bl, #0x80 je cirrus_vesa_07h_1 cmp bl, #0x01 je cirrus_vesa_07h_2 jb cirrus_vesa_07h_1 mov ax, #0x0100 ret cirrus_vesa_07h_1: push dx call cirrus_get_bpp_bytes mov bl, al xor bh, bh mov ax, cx mul bx pop bx push ax call cirrus_get_line_offset mul bx pop bx add ax, bx jnc cirrus_vesa_07h_3 inc dx cirrus_vesa_07h_3: push dx and dx, #0x0003 mov bx, #0x04 div bx pop dx shr dx, #2 call cirrus_set_start_addr mov ax, #0x004f ret cirrus_vesa_07h_2: call cirrus_get_start_addr shl dx, #2 push dx mov bx, #0x04 mul bx pop bx or dx, bx push ax call cirrus_get_line_offset mov bx, ax pop ax div bx push ax push dx call cirrus_get_bpp_bytes mov bl, al xor bh, bh pop ax xor dx, dx div bx mov cx, ax pop dx mov ax, #0x004f ret cirrus_vesa_10h: cmp bl, #0x00 jne cirrus_vesa_10h_01 mov bx, #0x0f30 mov ax, #0x004f ret cirrus_vesa_10h_01: cmp bl, #0x01 jne cirrus_vesa_10h_02 push dx push ds mov dx, #0x40 mov ds, dx mov [0xb9], bh pop ds pop dx mov ax, #0x004f ret cirrus_vesa_10h_02: cmp bl, #0x02 jne cirrus_vesa_unimplemented push dx push ds mov dx, #0x40 mov ds, dx mov bh, [0xb9] pop ds pop dx mov ax, #0x004f ret cirrus_vesa_unimplemented: mov ax, #0x014F ;; not implemented ret ;; in ax:vesamode, out ax:cirrusmode cirrus_vesamode_to_mode: push ds push cx push si push cs pop ds mov cx, #0xffff mov si, #_cirrus_vesa_modelist cvtm_1: cmp [si],ax jz cvtm_2 cmp [si],cx jz cvtm_2 add si, #4 jmp cvtm_1 cvtm_2: mov ax,[si+2] pop si pop cx pop ds ret ; cirrus_get_crtc ;; NOTE - may be called in protected mode cirrus_get_crtc: push ds push ax mov dx, #0x3cc in al, dx and al, #0x01 shl al, #5 mov dx, #0x3b4 add dl, al pop ax pop ds ret ;; in - al:mode, out - cflag:result, si:table, ax:destroyed cirrus_get_modeentry: and al, #0x7f cirrus_get_modeentry_nomask: mov si, #_cirrus_modes cgm_1: db 0x2e ;; cs: mov ah, [si] cmp al, ah jz cgm_2 cmp ah, #0xff jz cgm_4 add si, # CIRRUS_MODE_SIZE jmp cgm_1 cgm_4: xor si, si stc ;; video mode is not supported jmp cgm_3 cgm_2: clc ;; video mode is supported cgm_3: ret ;; out - al:bytes per pixel cirrus_get_bpp_bytes: push dx mov dx, #0x03c4 mov al, #0x07 out dx, al inc dx in al, dx and al, #0x0e cmp al, #0x06 jne cirrus_get_bpp_bytes_1 and al, #0x02 cirrus_get_bpp_bytes_1: shr al, #1 cmp al, #0x04 je cirrus_get_bpp_bytes_2 inc al cirrus_get_bpp_bytes_2: pop dx ret ;; in - ax: new line offset cirrus_set_line_offset: shr ax, #3 push ax call cirrus_get_crtc mov al, #0x13 out dx, al inc dx pop ax out dx, al dec dx mov al, #0x1b out dx, al inc dx shl ah, #4 in al, dx and al, #ef or al, ah out dx, al ret ;; out - ax: active line offset cirrus_get_line_offset: push dx push bx call cirrus_get_crtc mov al, #0x13 out dx, al inc dx in al, dx mov bl, al dec dx mov al, #0x1b out dx, al inc dx in al, dx mov ah, al shr ah, #4 and ah, #0x01 mov al, bl shl ax, #3 pop bx pop dx ret ;; in - si: table ;; out - ax: line offset for mode cirrus_get_line_offset_entry: push bx mov bx, [si+14] ;; crtc table push bx offset_loop1: mov ax, [bx] cmp al, #0x13 je offset_found1 inc bx inc bx jnz offset_loop1 offset_found1: xor al, al shr ax, #5 pop bx push ax offset_loop2: mov ax, [bx] cmp al, #0x1b je offset_found2 inc bx inc bx jnz offset_loop2 offset_found2: pop bx and ax, #0x1000 shr ax, #1 or ax, bx pop bx ret ;; in - new address in DX:AX cirrus_set_start_addr: push bx push dx push ax call cirrus_get_crtc mov al, #0x0d out dx, al inc dx pop ax out dx, al dec dx mov al, #0x0c out dx, al inc dx mov al, ah out dx, al dec dx mov al, #0x1d out dx, al inc dx in al, dx and al, #0x7f pop bx mov ah, bl shl bl, #4 and bl, #0x80 or al, bl out dx, al dec dx mov bl, ah and ah, #0x01 shl bl, #1 and bl, #0x0c or ah, bl mov al, #0x1b out dx, al inc dx in al, dx and al, #0xf2 or al, ah out dx, al pop bx ret ;; out - current address in DX:AX cirrus_get_start_addr: push bx call cirrus_get_crtc mov al, #0x0c out dx, al inc dx in al, dx mov ah, al dec dx mov al, #0x0d out dx, al inc dx in al, dx push ax dec dx mov al, #0x1b out dx, al inc dx in al, dx dec dx mov bl, al and al, #0x01 and bl, #0x0c shr bl, #1 or bl, al mov al, #0x1d out dx, al inc dx in al, dx and al, #0x80 shr al, #4 or bl, al mov dl, bl xor dh, dh pop ax pop bx ret cirrus_clear_vram: pusha push es mov si, ax call cirrus_enable_16k_granularity call cirrus_extbios_85h shl al, #2 mov bl, al xor ah,ah cirrus_clear_vram_1: mov al, #0x09 mov dx, #0x3ce out dx, ax push ax mov cx, #0xa000 mov es, cx xor di, di mov ax, si mov cx, #8192 cld rep stosw pop ax inc ah cmp ah, bl jne cirrus_clear_vram_1 xor ah,ah mov dx, #0x3ce out dx, ax pop es popa ret cirrus_extbios_handlers: ;; 80h dw cirrus_extbios_80h dw cirrus_extbios_81h dw cirrus_extbios_82h dw cirrus_extbios_unimplemented ;; 84h dw cirrus_extbios_unimplemented dw cirrus_extbios_85h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 88h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 8Ch dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 90h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 94h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; 98h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_9Ah dw cirrus_extbios_unimplemented ;; 9Ch dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; A0h dw cirrus_extbios_A0h dw cirrus_extbios_A1h dw cirrus_extbios_A2h dw cirrus_extbios_unimplemented ;; A4h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; A8h dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented ;; ACh dw cirrus_extbios_unimplemented dw cirrus_extbios_unimplemented dw cirrus_extbios_AEh dw cirrus_extbios_unimplemented cirrus_vesa_handlers: ;; 00h dw cirrus_vesa_00h dw cirrus_vesa_01h dw cirrus_vesa_02h dw cirrus_vesa_03h ;; 04h dw cirrus_vesa_unimplemented dw cirrus_vesa_05h dw cirrus_vesa_06h dw cirrus_vesa_07h ;; 08h dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented ;; 0Ch dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented dw cirrus_vesa_unimplemented ;; 10h dw cirrus_vesa_10h ASM_END #ifdef CIRRUS_VESA3_PMINFO ASM_START cirrus_vesa_pminfo: /* + 0 */ .byte 0x50,0x4d,0x49,0x44 ;; signature[4] /* + 4 */ dw cirrus_vesa_pmbios_entry ;; entry_bios dw cirrus_vesa_pmbios_init ;; entry_init /* + 8 */ cirrus_vesa_sel0000_data: dw 0x0000 ;; sel_00000 cirrus_vesa_selA000_data: dw 0xA000 ;; sel_A0000 /* +12 */ cirrus_vesa_selB000_data: dw 0xB000 ;; sel_B0000 cirrus_vesa_selB800_data: dw 0xB800 ;; sel_B8000 /* +16 */ cirrus_vesa_selC000_data: dw 0xC000 ;; sel_C0000 cirrus_vesa_is_protected_mode: ;; protected mode flag and checksum dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \ + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01 ASM_END #endif // CIRRUS_VESA3_PMINFO #ifdef CIRRUS_DEBUG static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; { if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05)) printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); } #endif vgabios-0.7a/BUGS0000644000175000017500000000024711653242734013526 0ustar guillemguillemNot all the functions have been implemented yet. Please report any bugs to the LGPL'd VGABIOS project page on Savannah: http://savannah.nongnu.org/projects/vgabios vgabios-0.7a/dataseghack0000755000175000017500000000103307434231025015213 0ustar guillemguillem#!/bin/bash awk \ 'BEGIN { }\ /^\.text/,/DATA_SEG_DEFS_HERE/ { print }\ END { }'\ $1 > temp.awk.1 awk \ 'BEGIN { i = 0; last = "hello" }\ /BLOCK_STRINGS_BEGIN/,/^\.bss/ { if ( i > 1 ) { print last } last = $0; i = i + 1 }\ END { }'\ $1 > temp.awk.2 awk \ 'BEGIN { }\ /DATA_SEG_DEFS_HERE/,/BLOCK_STRINGS_BEGIN/ { print }\ END { }'\ $1 > temp.awk.3 cp $1 $1.orig cat temp.awk.1 temp.awk.2 temp.awk.3 | sed -e 's/^\.data//' -e 's/^\.bss//' -e 's/^\.text//' > $1 /bin/rm -f temp.awk.1 temp.awk.2 temp.awk.3 $1.orig vgabios-0.7a/vgabios.c0000644000175000017500000025661211646311631014645 0ustar guillemguillem// ============================================================================================ /* * vgabios.c */ // ============================================================================================ // // Copyright (C) 2001-2008 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. // // ============================================================================================ // // This file contains code ripped from : // - rombios.c of plex86 // // This VGA Bios contains fonts from : // - fntcol16.zip (c) by Joseph Gil avalable at : // ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip // These fonts are public domain // // This VGA Bios is based on information taken from : // - Kevin Lawton's vga card emulation for bochs/plex86 // - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html // - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ // - Michael Abrash's Graphics Programming Black Book // - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex // - DOSEMU 1.0.1 source code for several tables values and formulas // // Thanks for patches, comments and ideas to : // - techt@pikeonline.net // // ============================================================================================ #include "vgabios.h" #ifdef VBE #include "vbe.h" #endif #define USE_BX_INFO /* Declares */ static Bit8u read_byte(); static Bit16u read_word(); static void write_byte(); static void write_word(); static Bit8u inb(); static Bit16u inw(); static void outb(); static void outw(); static Bit16u get_SS(); // Output static void printf(); static void unimplemented(); static void unknown(); static Bit8u find_vga_entry(); static void load_dac_palette(); static void memsetb(); static void memsetw(); static void memcpyb(); static void memcpyw(); static void biosfn_set_video_mode(); static void biosfn_set_cursor_shape(); static void biosfn_set_cursor_pos(); static void biosfn_get_cursor_pos(); static void biosfn_set_active_page(); static void biosfn_scroll(); static void biosfn_read_char_attr(); static void biosfn_write_char_attr(); static void biosfn_write_char_only(); static void biosfn_write_pixel(); static void biosfn_read_pixel(); static void biosfn_write_teletype(); static void biosfn_perform_gray_scale_summing(); static void biosfn_load_text_user_pat(); static void biosfn_load_text_8_14_pat(); static void biosfn_load_text_8_8_pat(); static void biosfn_load_text_8_16_pat(); static void biosfn_load_gfx_8_8_chars(); static void biosfn_load_gfx_user_chars(); static void biosfn_load_gfx_8_14_chars(); static void biosfn_load_gfx_8_8_dd_chars(); static void biosfn_load_gfx_8_16_chars(); static void biosfn_get_font_info(); static void biosfn_alternate_prtsc(); static void biosfn_switch_video_interface(); static void biosfn_enable_video_refresh_control(); static void biosfn_write_string(); static void biosfn_read_state_info(); static void biosfn_read_video_state_size(); static Bit16u biosfn_save_video_state(); static Bit16u biosfn_restore_video_state(); extern Bit8u video_save_pointer_table[]; // This is for compiling with gcc2 and gcc3 #define ASM_START #asm #define ASM_END #endasm ASM_START MACRO SET_INT_VECTOR push ds xor ax, ax mov ds, ax mov ax, ?3 mov ?1*4, ax mov ax, ?2 mov ?1*4+2, ax pop ds MEND ASM_END ASM_START .text .rom .org 0 use16 386 vgabios_start: .byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */ .byte 0x40 /* BIOS extension length in units of 512 bytes */ vgabios_entry_point: jmp vgabios_init_func #ifdef PCIBIOS .org 0x18 .word vgabios_pci_data #endif // Info from Bart Oldeman .org 0x1e .ascii "IBM" .byte 0x00 vgabios_name: .ascii "Plex86/Bochs VGABios" #ifdef PCIBIOS .ascii " (PCI)" #endif .ascii " " .byte 0x00 vgabios_version: #ifndef VGABIOS_VERS .ascii "current-cvs" #else .ascii VGABIOS_VERS #endif .ascii " " vgabios_date: .ascii VGABIOS_DATE .byte 0x0a,0x0d .byte 0x00 vgabios_copyright: .ascii "(C) 2008 the LGPL VGABios developers Team" .byte 0x0a,0x0d .byte 0x00 vgabios_license: .ascii "This VGA/VBE Bios is released under the GNU LGPL" .byte 0x0a,0x0d .byte 0x0a,0x0d .byte 0x00 vgabios_website: .ascii "Please visit :" .byte 0x0a,0x0d ;;.ascii " . http://www.plex86.org" ;;.byte 0x0a,0x0d .ascii " . http://bochs.sourceforge.net" .byte 0x0a,0x0d .ascii " . http://www.nongnu.org/vgabios" .byte 0x0a,0x0d .byte 0x0a,0x0d .byte 0x00 #ifdef PCIBIOS vgabios_pci_data: .ascii "PCIR" #ifdef CIRRUS .word 0x1013 .word 0x00b8 // CLGD5446 #elif defined(PCI_VID) && defined(PCI_DID) .word PCI_VID .word PCI_DID #elif defined(VBE) .word 0x1234 .word 0x1111 // Bochs VBE support #else #error "Unknown PCI vendor and device id" #endif .word 0 // reserved .word 0x18 // dlen .byte 0 // revision .byte 0x0 // class,hi: vga display .word 0x300 // class,lo: vga display .word 0x40 // bios size .word 1 // revision .byte 0 // intel x86 data .byte 0x80 // last image .word 0 // reserved #endif ;; ============================================================================================ ;; ;; Init Entry point ;; ;; ============================================================================================ vgabios_init_func: ;; init vga card call init_vga_card ;; init basic bios vars call init_bios_area #ifdef VBE ;; init vbe functions call vbe_init #endif ;; set int10 vect SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler) #ifdef CIRRUS call cirrus_init #endif ;; display splash screen call _display_splash_screen ;; init video mode and clear the screen mov ax,#0x0003 int #0x10 ;; show info call _display_info #ifdef VBE ;; show vbe info call vbe_display_info #endif #ifdef CIRRUS ;; show cirrus info call cirrus_display_info #endif retf ASM_END /* * int10 handled here */ ASM_START vgabios_int10_handler: pushf #ifdef DEBUG push es push ds pusha mov bx, #0xc000 mov ds, bx call _int10_debugmsg popa pop ds pop es #endif cmp ah, #0x0f jne int10_test_1A call biosfn_get_video_mode jmp int10_end int10_test_1A: cmp ah, #0x1a jne int10_test_0B call biosfn_group_1A jmp int10_end int10_test_0B: cmp ah, #0x0b jne int10_test_1103 call biosfn_group_0B jmp int10_end int10_test_1103: cmp ax, #0x1103 jne int10_test_12 call biosfn_set_text_block_specifier jmp int10_end int10_test_12: cmp ah, #0x12 jne int10_test_101B cmp bl, #0x10 jne int10_test_BL30 call biosfn_get_ega_info jmp int10_end int10_test_BL30: cmp bl, #0x30 jne int10_test_BL31 call biosfn_select_vert_res jmp int10_end int10_test_BL31: cmp bl, #0x31 jne int10_test_BL32 call biosfn_enable_default_palette_loading jmp int10_end int10_test_BL32: cmp bl, #0x32 jne int10_test_BL33 call biosfn_enable_video_addressing jmp int10_end int10_test_BL33: cmp bl, #0x33 jne int10_test_BL34 call biosfn_enable_grayscale_summing jmp int10_end int10_test_BL34: cmp bl, #0x34 jne int10_normal call biosfn_enable_cursor_emulation jmp int10_end int10_test_101B: cmp ax, #0x101b je int10_normal cmp ah, #0x10 #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, #0x4f jne int10_normal cmp al, #0x03 jne int10_test_vbe_05 call vbe_biosfn_return_current_mode jmp int10_end int10_test_vbe_05: cmp al, #0x05 jne int10_test_vbe_06 call vbe_biosfn_display_window_control jmp int10_end int10_test_vbe_06: cmp al, #0x06 jne int10_test_vbe_07 call vbe_biosfn_set_get_logical_scan_line_length jmp int10_end int10_test_vbe_07: cmp al, #0x07 jne int10_test_vbe_08 call vbe_biosfn_set_get_display_start jmp int10_end int10_test_vbe_08: cmp al, #0x08 jne int10_test_vbe_0A call vbe_biosfn_set_get_dac_palette_format jmp int10_end int10_test_vbe_0A: cmp al, #0x0A jne int10_normal call vbe_biosfn_return_protected_mode_interface jmp int10_end #endif int10_normal: push es push ds pusha ;; We have to set ds to access the right data segment mov bx, #0xc000 mov ds, bx call _int10_func popa pop ds pop es int10_end: popf iret ASM_END #include "vgatables.h" #include "vgafonts.h" /* * Boot time harware inits */ ASM_START init_vga_card: ;; switch to color mode and enable CPU access 480 lines mov dx, #0x3C2 mov al, #0xC3 outb dx,al ;; more than 64k 3C4/04 mov dx, #0x3C4 mov al, #0x04 outb dx,al mov dx, #0x3C5 mov al, #0x02 outb dx,al #if defined(USE_BX_INFO) || defined(DEBUG) mov bx, #msg_vga_init push bx call _printf inc sp inc sp #endif ret #if defined(USE_BX_INFO) || defined(DEBUG) msg_vga_init: .ascii "VGABios $Id: vgabios.c,v 1.75 2011/10/15 14:07:21 vruppert Exp $" .byte 0x0d,0x0a,0x00 #endif ASM_END // -------------------------------------------------------------------------------------------- /* * Boot time bios area inits */ ASM_START init_bios_area: push ds mov ax, # BIOSMEM_SEG mov ds, ax ;; init detected hardware BIOS Area mov bx, # BIOSMEM_INITIAL_MODE mov ax, [bx] and ax, #0xffcf ;; set 80x25 color (not clear from RBIL but usual) or ax, #0x0020 mov [bx], ax ;; Just for the first int10 find its children ;; the default char height mov bx, # BIOSMEM_CHAR_HEIGHT mov al, #0x10 mov [bx], al ;; Clear the screen mov bx, # BIOSMEM_VIDEO_CTL mov al, #0x60 mov [bx], al ;; Set the basic screen we have mov bx, # BIOSMEM_SWITCHES mov al, #0xf9 mov [bx], al ;; Set the basic modeset options mov bx, # BIOSMEM_MODESET_CTL mov al, #0x51 mov [bx], al ;; Set the default MSR mov bx, # BIOSMEM_CURRENT_MSR mov al, #0x09 mov [bx], al pop ds ret _video_save_pointer_table: .word _video_param_table .word 0xc000 .word 0 /* XXX: fill it */ .word 0 .word 0 /* XXX: fill it */ .word 0 .word 0 /* XXX: fill it */ .word 0 .word 0 /* XXX: fill it */ .word 0 .word 0 /* XXX: fill it */ .word 0 .word 0 /* XXX: fill it */ .word 0 ASM_END // -------------------------------------------------------------------------------------------- /* * Boot time Splash screen */ static void display_splash_screen() { } // -------------------------------------------------------------------------------------------- /* * Tell who we are */ static void display_info() { ASM_START mov ax,#0xc000 mov ds,ax mov si,#vgabios_name call _display_string mov si,#vgabios_version call _display_string ;;mov si,#vgabios_copyright ;;call _display_string ;;mov si,#crlf ;;call _display_string mov si,#vgabios_license call _display_string mov si,#vgabios_website call _display_string ASM_END } static void display_string() { // Get length of string ASM_START mov ax,ds mov es,ax mov di,si xor cx,cx not cx xor al,al cld repne scasb not cx dec cx push cx mov ax,#0x0300 mov bx,#0x0000 int #0x10 pop cx mov ax,#0x1301 mov bx,#0x000b mov bp,si int #0x10 ASM_END } // -------------------------------------------------------------------------------------------- #ifdef DEBUG static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; { // 0E is write char... if(GET_AH()!=0x0E) printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); } #endif // -------------------------------------------------------------------------------------------- /* * int10 main dispatcher */ static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; { // BIOS functions switch(GET_AH()) { case 0x00: biosfn_set_video_mode(GET_AL()); switch(GET_AL()&0x7F) {case 6: SET_AL(0x3F); break; case 0: case 1: case 2: case 3: case 4: case 5: case 7: SET_AL(0x30); break; default: SET_AL(0x20); } break; case 0x01: biosfn_set_cursor_shape(GET_CH(),GET_CL()); break; case 0x02: biosfn_set_cursor_pos(GET_BH(),DX); break; case 0x03: biosfn_get_cursor_pos(GET_BH(),&CX,&DX); break; case 0x04: // Read light pen pos (unimplemented) #ifdef DEBUG unimplemented(); #endif AX=0x00; BX=0x00; CX=0x00; DX=0x00; break; case 0x05: biosfn_set_active_page(GET_AL()); break; case 0x06: biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP); break; case 0x07: biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN); break; case 0x08: biosfn_read_char_attr(GET_BH(),&AX); break; case 0x09: biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX); break; case 0x0A: biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX); break; case 0x0C: biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX); break; case 0x0D: biosfn_read_pixel(GET_BH(),CX,DX,&AX); break; case 0x0E: // Ralf Brown Interrupt list is WRONG on bh(page) // We do output only on the current page ! biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR); break; case 0x10: // All other functions of group AH=0x10 rewritten in assembler biosfn_perform_gray_scale_summing(BX,CX); break; case 0x11: switch(GET_AL()) { case 0x00: case 0x10: biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH()); break; case 0x01: case 0x11: biosfn_load_text_8_14_pat(GET_AL(),GET_BL()); break; case 0x02: case 0x12: biosfn_load_text_8_8_pat(GET_AL(),GET_BL()); break; case 0x04: case 0x14: biosfn_load_text_8_16_pat(GET_AL(),GET_BL()); break; case 0x20: biosfn_load_gfx_8_8_chars(ES,BP); break; case 0x21: biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL()); break; case 0x22: biosfn_load_gfx_8_14_chars(GET_BL()); break; case 0x23: biosfn_load_gfx_8_8_dd_chars(GET_BL()); break; case 0x24: biosfn_load_gfx_8_16_chars(GET_BL()); break; case 0x30: biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX); break; #ifdef DEBUG default: unknown(); #endif } break; case 0x12: switch(GET_BL()) { case 0x20: biosfn_alternate_prtsc(); break; case 0x35: biosfn_switch_video_interface(GET_AL(),ES,DX); SET_AL(0x12); break; case 0x36: biosfn_enable_video_refresh_control(GET_AL()); SET_AL(0x12); break; #ifdef DEBUG default: unknown(); #endif } break; case 0x13: biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP); break; case 0x1B: biosfn_read_state_info(BX,ES,DI); SET_AL(0x1B); break; case 0x1C: switch(GET_AL()) { case 0x00: biosfn_read_video_state_size(CX,&BX); break; case 0x01: biosfn_save_video_state(CX,ES,BX); break; case 0x02: biosfn_restore_video_state(CX,ES,BX); break; #ifdef DEBUG default: unknown(); #endif } SET_AL(0x1C); break; #ifdef VBE case 0x4f: if (vbe_has_vbe_display()) { switch(GET_AL()) { case 0x00: vbe_biosfn_return_controller_information(&AX,ES,DI); break; case 0x01: vbe_biosfn_return_mode_information(&AX,CX,ES,DI); break; case 0x02: vbe_biosfn_set_mode(&AX,BX,ES,DI); break; case 0x04: vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); break; case 0x09: //FIXME #ifdef DEBUG unimplemented(); #endif // function failed AX=0x100; break; case 0x0A: //FIXME #ifdef DEBUG unimplemented(); #endif // function failed AX=0x100; break; default: #ifdef DEBUG unknown(); #endif // function failed AX=0x100; } } else { // No VBE display AX=0x0100; } break; #endif #ifdef DEBUG default: unknown(); #endif } } static void load_dac_palette(num) Bit8u num; { Bit8u *palette; Bit16u i; // Set the whole dac always, from 0 outb(VGAREG_DAC_WRITE_ADDRESS,0x00); // From which palette switch (num) { case 0: palette=&palette0; break; case 1: palette=&palette1; break; case 2: palette=&palette2; break; case 3: palette=&palette3; break; } // Always 256*3 values for (i=0;i<0x0100;i++) { if(i<=dac_regs[num]) { outb(VGAREG_DAC_DATA,palette[(i*3)+0]); outb(VGAREG_DAC_DATA,palette[(i*3)+1]); outb(VGAREG_DAC_DATA,palette[(i*3)+2]); } else { outb(VGAREG_DAC_DATA,0); outb(VGAREG_DAC_DATA,0); outb(VGAREG_DAC_DATA,0); } } } // ============================================================================================ // // BIOS functions // // ============================================================================================ static void biosfn_set_video_mode(mode) Bit8u mode; {// mode: Bit 7 is 1 if no clear screen // Should we clear the screen ? Bit8u noclearmem=mode&0x80; Bit8u line,mmask,*palette,vpti; Bit16u i,twidth,theightm1,cheight; Bit8u modeset_ctl,video_ctl,vga_switches; Bit16u crtc_addr; #ifdef VBE if (vbe_has_vbe_display()) { dispi_set_enable(VBE_DISPI_DISABLED); } #endif // def VBE // The real mode mode=mode&0x7f; // find the entry in the video modes line=find_vga_entry(mode); #ifdef DEBUG printf("mode search %02x found line %02x\n",mode,line); #endif if(line==0xFF) return; vpti=line_to_vpti[line]; twidth=video_param_table[vpti].twidth; theightm1=video_param_table[vpti].theightm1; cheight=video_param_table[vpti].cheight; // Read the bios vga control video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); // Read the bios vga switches vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES); // Read the bios mode set control modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); // Then we know the number of lines // FIXME // if palette loading (bit 3 of modeset ctl = 0) if((modeset_ctl&0x08)==0) { // Set the PEL mask outb(VGAREG_PEL_MASK,vga_modes[line].pelmask); load_dac_palette(vga_modes[line].dacmodel); if((modeset_ctl&0x02)==0x02) { biosfn_perform_gray_scale_summing(0x00, 0x100); } } // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); // Set Attribute Ctl for(i=0;i<=0x13;i++) {outb(VGAREG_ACTL_ADDRESS,i); outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]); } outb(VGAREG_ACTL_ADDRESS,0x14); outb(VGAREG_ACTL_WRITE_DATA,0x00); // Set Sequencer Ctl outb(VGAREG_SEQU_ADDRESS,0); outb(VGAREG_SEQU_DATA,0x03); for(i=1;i<=4;i++) {outb(VGAREG_SEQU_ADDRESS,i); outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]); } // Set Grafx Ctl for(i=0;i<=8;i++) {outb(VGAREG_GRDC_ADDRESS,i); outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]); } // Set CRTC address VGA or MDA crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; // Disable CRTC write protection outw(crtc_addr,0x0011); // Set CRTC regs for(i=0;i<=0x18;i++) {outb(crtc_addr,i); outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]); } // Set the misc register outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg); // Enable video outb(VGAREG_ACTL_ADDRESS,0x20); inb(VGAREG_ACTL_RESET); if(noclearmem==0x00) { if(vga_modes[line].class==TEXT) { memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k } else { if(mode<0x0d) { memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k } else { outb( VGAREG_SEQU_ADDRESS, 0x02 ); mmask = inb( VGAREG_SEQU_DATA ); outb( VGAREG_SEQU_DATA, 0x0f ); // all planes memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k outb( VGAREG_SEQU_DATA, mmask ); } } } // Set the BIOS mem write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l); write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1); write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem)); write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); // FIXME We nearly have the good tables. to be reworked write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table); write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000); // FIXME write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... // Set cursor shape if(vga_modes[line].class==TEXT) { biosfn_set_cursor_shape(0x06,0x07); } // Set cursor pos for page 0..7 for(i=0;i<8;i++) biosfn_set_cursor_pos(i,0x0000); // Set active page 0 biosfn_set_active_page(0x00); // Write the fonts in memory if(vga_modes[line].class==TEXT) { ASM_START ;; copy and activate 8x16 font mov ax, #0x1104 mov bl, #0x00 int #0x10 mov ax, #0x1103 mov bl, #0x00 int #0x10 ASM_END } // Set the ints 0x1F and 0x43 ASM_START SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8) ASM_END switch(cheight) {case 8: ASM_START SET_INT_VECTOR(0x43, #0xC000, #_vgafont8) ASM_END break; case 14: ASM_START SET_INT_VECTOR(0x43, #0xC000, #_vgafont14) ASM_END break; case 16: ASM_START SET_INT_VECTOR(0x43, #0xC000, #_vgafont16) ASM_END break; } } // -------------------------------------------------------------------------------------------- static void biosfn_set_cursor_shape (CH,CL) Bit8u CH;Bit8u CL; {Bit16u cheight,curs,crtc_addr; Bit8u modeset_ctl; CH&=0x3f; CL&=0x1f; curs=(CH<<8)+CL; write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs); modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20)) { if(CL!=(CH+1)) { CH = ((CH+1) * cheight / 8) -1; } else { CH = ((CL+1) * cheight / 8) - 2; } CL = ((CL+1) * cheight / 8) - 1; } // CTRC regs 0x0a and 0x0b crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr,0x0a); outb(crtc_addr+1,CH); outb(crtc_addr,0x0b); outb(crtc_addr+1,CL); } // -------------------------------------------------------------------------------------------- static void biosfn_set_cursor_pos (page, cursor) Bit8u page;Bit16u cursor; { Bit8u xcurs,ycurs,current; Bit16u nbcols,nbrows,address,crtc_addr; // Should not happen... if(page>7)return; // Bios cursor pos write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor); // Set the hardware cursor current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); if(page==current) { // Get the dimensions nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Calculate the address knowing nbcols nbrows and page num address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols; // CRTC regs 0x0e and 0x0f crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr,0x0e); outb(crtc_addr+1,(address&0xff00)>>8); outb(crtc_addr,0x0f); outb(crtc_addr+1,address&0x00ff); } } // -------------------------------------------------------------------------------------------- static void biosfn_get_cursor_pos (page,shape, pos) Bit8u page;Bit16u *shape;Bit16u *pos; { Bit16u ss=get_SS(); // Default write_word(ss, shape, 0); write_word(ss, pos, 0); if(page>7)return; // FIXME should handle VGA 14/16 lines write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2)); } // -------------------------------------------------------------------------------------------- static void biosfn_set_active_page (page) Bit8u page; { Bit16u cursor,dummy,crtc_addr; Bit16u nbcols,nbrows,address; Bit8u mode,line; if(page>7)return; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get pos curs pos for the right page biosfn_get_cursor_pos(page,&dummy,&cursor); if(vga_modes[line].class==TEXT) { // Get the dimensions nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; // Calculate the address knowing nbcols nbrows and page num address=SCREEN_MEM_START(nbcols,nbrows,page); write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address); // Start address address=SCREEN_IO_START(nbcols,nbrows,page); } else { address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l); } // CRTC regs 0x0c and 0x0d crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr,0x0c); outb(crtc_addr+1,(address&0xff00)>>8); outb(crtc_addr,0x0d); outb(crtc_addr+1,address&0x00ff); // And change the BIOS page write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); #ifdef DEBUG printf("Set active page %02x address %04x\n",page,address); #endif // Display the cursor, now the page is active biosfn_set_cursor_pos(page,cursor); } // -------------------------------------------------------------------------------------------- static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight) Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; { Bit16u src,dest; Bit8u i; src=ysrc*cheight*nbcols+xstart; dest=ydest*cheight*nbcols+xstart; outw(VGAREG_GRDC_ADDRESS, 0x0105); for(i=0;i>1)+xstart; dest=((ydest*cheight*nbcols)>>1)+xstart; for(i=0;i>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols); else memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols); } } // -------------------------------------------------------------------------------------------- static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr) Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; { Bit16u dest; Bit8u i; dest=((ystart*cheight*nbcols)>>1)+xstart; for(i=0;i>1)*nbcols,attr,cols); else memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols); } } // -------------------------------------------------------------------------------------------- static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir) Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir; { // page == 0xFF if current Bit8u mode,line,cheight,bpp,cols; Bit16u nbcols,nbrows,i; Bit16u address; if(rul>rlr)return; if(cul>clr)return; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); // Get the current page if(page==0xFF) page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); if(rlr>=nbrows)rlr=nbrows-1; if(clr>=nbcols)clr=nbcols-1; if(nblines>nbrows)nblines=0; cols=clr-cul+1; if(vga_modes[line].class==TEXT) { // Compute the address address=SCREEN_MEM_START(nbcols,nbrows,page); #ifdef DEBUG printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page); #endif if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) { memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols); } else {// if Scroll up if(dir==SCROLL_UP) {for(i=rul;i<=rlr;i++) { if((i+nblines>rlr)||(nblines==0)) memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); else memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols); } } else {for(i=rlr;i>=rul;i--) { if((irlr) break; } } } } else { // FIXME gfx mode not complete cheight=read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch(vga_modes[line].memmodel) { case PLANAR4: case PLANAR1: if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) { outw(VGAREG_GRDC_ADDRESS, 0x0205); memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight); outw(VGAREG_GRDC_ADDRESS, 0x0005); } else {// if Scroll up if(dir==SCROLL_UP) {for(i=rul;i<=rlr;i++) { if((i+nblines>rlr)||(nblines==0)) vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); else vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight); } } else {for(i=rlr;i>=rul;i--) { if((irlr) break; } } } break; case CGA: bpp=vga_modes[line].pixbits; if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) { memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp); } else { if(bpp==2) { cul<<=1; cols<<=1; nbcols<<=1; } // if Scroll up if(dir==SCROLL_UP) {for(i=rul;i<=rlr;i++) { if((i+nblines>rlr)||(nblines==0)) vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); else vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight); } } else {for(i=rlr;i>=rul;i--) { if((irlr) break; } } } break; #ifdef DEBUG default: printf("Scroll in graphics mode "); unimplemented(); #endif } } } // -------------------------------------------------------------------------------------------- static void biosfn_read_char_attr (page,car) Bit8u page;Bit16u *car; {Bit16u ss=get_SS(); Bit8u xcurs,ycurs,mode,line; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT) { // Compute the address address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; write_word(ss,car,read_word(vga_modes[line].sstart,address)); } else { // FIXME gfx mode #ifdef DEBUG unimplemented(); #endif } } // -------------------------------------------------------------------------------------------- static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight) Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight; { Bit8u i,j,mask; Bit8u *fdata; Bit16u addr,dest,src; switch(cheight) {case 14: fdata = &vgafont14; break; case 16: fdata = &vgafont16; break; default: fdata = &vgafont8; } addr=xcurs+ycurs*cheight*nbcols; src = car * cheight; outw(VGAREG_SEQU_ADDRESS, 0x0f02); outw(VGAREG_GRDC_ADDRESS, 0x0205); if(attr&0x80) { outw(VGAREG_GRDC_ADDRESS, 0x1803); } else { outw(VGAREG_GRDC_ADDRESS, 0x0003); } for(i=0;i>j; outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); read_byte(0xa000,dest); if(fdata[src+i]&mask) { write_byte(0xa000,dest,attr&0x0f); } else { write_byte(0xa000,dest,0x00); } } } ASM_START mov dx, # VGAREG_GRDC_ADDRESS mov ax, #0xff08 out dx, ax mov ax, #0x0005 out dx, ax mov ax, #0x0003 out dx, ax ASM_END } // -------------------------------------------------------------------------------------------- static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp) Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp; { Bit8u i,j,mask,data; Bit8u *fdata; Bit16u addr,dest,src; fdata = &vgafont8; addr=(xcurs*bpp)+ycurs*320; src = car * 8; for(i=0;i<8;i++) { dest=addr+(i>>1)*80; if (i & 1) dest += 0x2000; mask = 0x80; if (bpp == 1) { if (attr & 0x80) { data = read_byte(0xb800,dest); } else { data = 0x00; } for(j=0;j<8;j++) { if (fdata[src+i] & mask) { if (attr & 0x80) { data ^= (attr & 0x01) << (7-j); } else { data |= (attr & 0x01) << (7-j); } } mask >>= 1; } write_byte(0xb800,dest,data); } else { while (mask > 0) { if (attr & 0x80) { data = read_byte(0xb800,dest); } else { data = 0x00; } for(j=0;j<4;j++) { if (fdata[src+i] & mask) { if (attr & 0x80) { data ^= (attr & 0x03) << ((3-j)*2); } else { data |= (attr & 0x03) << ((3-j)*2); } } mask >>= 1; } write_byte(0xb800,dest,data); dest += 1; } } } } // -------------------------------------------------------------------------------------------- static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols) Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols; { Bit8u i,j,mask,data; Bit8u *fdata; Bit16u addr,dest,src; fdata = &vgafont8; addr=xcurs*8+ycurs*nbcols*64; src = car * 8; for(i=0;i<8;i++) { dest=addr+i*nbcols*8; mask = 0x80; for(j=0;j<8;j++) { data = 0x00; if (fdata[src+i] & mask) { data = attr; } write_byte(0xa000,dest+j,data); mask >>= 1; } } } // -------------------------------------------------------------------------------------------- static void biosfn_write_char_attr (car,page,attr,count) Bit8u car;Bit8u page;Bit8u attr;Bit16u count; { Bit8u cheight,xcurs,ycurs,mode,line,bpp; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT) { // Compute the address address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; dummy=((Bit16u)attr<<8)+car; memsetw(vga_modes[line].sstart,address,dummy,count); } else { // FIXME gfx mode not complete cheight=read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); bpp=vga_modes[line].pixbits; while((count-->0) && (xcurs>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); if(vga_modes[line].class==TEXT) { // Compute the address address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; while(count-->0) {write_byte(vga_modes[line].sstart,address,car); address+=2; } } else { // FIXME gfx mode not complete cheight=read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); bpp=vga_modes[line].pixbits; while((count-->0) && (xcurs> (CX & 0x07); outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); outw(VGAREG_GRDC_ADDRESS, 0x0205); data = read_byte(0xa000,addr); if (AL & 0x80) { outw(VGAREG_GRDC_ADDRESS, 0x1803); } write_byte(0xa000,addr,AL); ASM_START mov dx, # VGAREG_GRDC_ADDRESS mov ax, #0xff08 out dx, ax mov ax, #0x0005 out dx, ax mov ax, #0x0003 out dx, ax ASM_END break; case CGA: if(vga_modes[line].pixbits==2) { addr=(CX>>2)+(DX>>1)*80; } else { addr=(CX>>3)+(DX>>1)*80; } if (DX & 1) addr += 0x2000; data = read_byte(0xb800,addr); if(vga_modes[line].pixbits==2) { attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); mask = 0x03 << ((3 - (CX & 0x03)) * 2); } else { attr = (AL & 0x01) << (7 - (CX & 0x07)); mask = 0x01 << (7 - (CX & 0x07)); } if (AL & 0x80) { data ^= attr; } else { data &= ~mask; data |= attr; } write_byte(0xb800,addr,data); break; case LINEAR8: addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); write_byte(0xa000,addr,AL); break; #ifdef DEBUG default: unimplemented(); #endif } } // -------------------------------------------------------------------------------------------- static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX; { Bit8u mode,line,mask,attr,data,i; Bit16u addr; Bit16u ss=get_SS(); // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; if(vga_modes[line].class==TEXT)return; switch(vga_modes[line].memmodel) { case PLANAR4: case PLANAR1: addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); mask = 0x80 >> (CX & 0x07); attr = 0x00; for(i=0;i<4;i++) { outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04); data = read_byte(0xa000,addr) & mask; if (data > 0) attr |= (0x01 << i); } break; case CGA: addr=(CX>>2)+(DX>>1)*80; if (DX & 1) addr += 0x2000; data = read_byte(0xb800,addr); if(vga_modes[line].pixbits==2) { attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; } else { attr = (data >> (7 - (CX & 0x07))) & 0x01; } break; case LINEAR8: addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); attr=read_byte(0xa000,addr); break; default: #ifdef DEBUG unimplemented(); #endif attr = 0; } write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr); } // -------------------------------------------------------------------------------------------- static void biosfn_write_teletype (car, page, attr, flag) Bit8u car;Bit8u page;Bit8u attr;Bit8u flag; {// flag = WITH_ATTR / NO_ATTR Bit8u cheight,xcurs,ycurs,mode,line,bpp; Bit16u nbcols,nbrows,address; Bit16u cursor,dummy; // special case if page is 0xff, use current page if(page==0xff) page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); // Get the mode mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); line=find_vga_entry(mode); if(line==0xFF)return; // Get the cursor pos for the page biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; // Get the dimensions nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); switch(car) { case 7: //FIXME should beep break; case 8: if(xcurs>0)xcurs--; break; case '\r': xcurs=0; break; case '\n': ycurs++; break; case '\t': do { biosfn_write_teletype(' ',page,attr,flag); biosfn_get_cursor_pos(page,&dummy,&cursor); xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; }while(xcurs%8==0); break; default: if(vga_modes[line].class==TEXT) { // Compute the address address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; // Write the char write_byte(vga_modes[line].sstart,address,car); if(flag==WITH_ATTR) write_byte(vga_modes[line].sstart,address+1,attr); } else { // FIXME gfx mode not complete cheight=read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); bpp=vga_modes[line].pixbits; switch(vga_modes[line].memmodel) { case PLANAR4: case PLANAR1: write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); break; case CGA: write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); break; case LINEAR8: write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); break; #ifdef DEBUG default: unimplemented(); #endif } } xcurs++; } // Do we need to wrap ? if(xcurs==nbcols) {xcurs=0; ycurs++; } // Do we need to scroll ? if(ycurs==nbrows) { if(vga_modes[line].class==TEXT) { address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2; attr=read_byte(vga_modes[line].sstart,address+1); biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); } else { biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); } ycurs-=1; } // Set the cursor for the page cursor=ycurs; cursor<<=8; cursor+=xcurs; biosfn_set_cursor_pos(page,cursor); } // -------------------------------------------------------------------------------------------- ASM_START 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, #0x80 mov bx, # BIOSMEM_CURRENT_MODE mov al, [bx] or al, ah mov bx, # BIOSMEM_NB_COLS mov ah, [bx] pop bx pop ds ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_group_10: cmp al, #0x00 jne int10_test_1001 jmp biosfn_set_single_palette_reg int10_test_1001: cmp al, #0x01 jne int10_test_1002 jmp biosfn_set_overscan_border_color int10_test_1002: cmp al, #0x02 jne int10_test_1003 jmp biosfn_set_all_palette_reg int10_test_1003: cmp al, #0x03 jne int10_test_1007 jmp biosfn_toggle_intensity int10_test_1007: cmp al, #0x07 jne int10_test_1008 jmp biosfn_get_single_palette_reg int10_test_1008: cmp al, #0x08 jne int10_test_1009 jmp biosfn_read_overscan_border_color int10_test_1009: cmp al, #0x09 jne int10_test_1010 jmp biosfn_get_all_palette_reg int10_test_1010: cmp al, #0x10 jne int10_test_1012 jmp biosfn_set_single_dac_reg int10_test_1012: cmp al, #0x12 jne int10_test_1013 jmp biosfn_set_all_dac_reg int10_test_1013: cmp al, #0x13 jne int10_test_1015 jmp biosfn_select_video_dac_color_page int10_test_1015: cmp al, #0x15 jne int10_test_1017 jmp biosfn_read_single_dac_reg int10_test_1017: cmp al, #0x17 jne int10_test_1018 jmp biosfn_read_all_dac_reg int10_test_1018: cmp al, #0x18 jne int10_test_1019 jmp biosfn_set_pel_mask int10_test_1019: cmp al, #0x19 jne int10_test_101A jmp biosfn_read_pel_mask int10_test_101A: cmp al, #0x1a jne int10_group_10_unknown jmp biosfn_read_video_dac_state int10_group_10_unknown: #ifdef DEBUG call _unknown #endif ret biosfn_set_single_palette_reg: cmp bl, #0x14 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, #0x20 out dx, al pop dx pop ax no_actl_reg1: ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_set_overscan_border_color: push bx mov bl, #0x11 call biosfn_set_single_palette_reg pop bx ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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, #0x00 mov dx, # VGAREG_ACTL_ADDRESS set_palette_loop: mov al, cl out dx, al seg es mov al, [bx] out dx, al inc bx inc cl cmp cl, #0x10 jne set_palette_loop mov al, #0x11 out dx, al seg es mov al, [bx] out dx, al mov al, #0x20 out dx, al pop dx pop cx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_toggle_intensity: push ax push bx push dx mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x10 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx and al, #0xf7 and bl, #0x01 shl bl, 3 or al, bl mov dx, # VGAREG_ACTL_ADDRESS out dx, al mov al, #0x20 out dx, al pop dx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_get_single_palette_reg: cmp bl, #0x14 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, #0x20 out dx, al pop dx pop ax no_actl_reg2: ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_read_overscan_border_color: push ax push bx mov bl, #0x11 call biosfn_get_single_palette_reg mov al, bh pop bx mov bh, al pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_get_all_palette_reg: push ax push bx push cx push dx mov bx, dx mov cl, #0x00 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 seg es mov [bx], al inc bx inc cl cmp cl, #0x10 jne get_palette_loop mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x11 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx seg es mov [bx], al mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x20 out dx, al pop dx pop cx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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 ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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: seg es mov al, [bx] out dx, al inc bx seg es mov al, [bx] out dx, al inc bx seg es mov al, [bx] out dx, al inc bx dec cx jnz set_dac_loop pop dx pop cx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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, #0x10 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx and bl, #0x01 jnz set_dac_page and al, #0x7f shl bh, 7 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, #0x14 out dx, al pop ax and al, #0x80 jnz set_dac_16_page shl bh, 2 set_dac_16_page: and bh, #0x0f mov al, bh out dx, al set_actl_normal: mov al, #0x20 out dx, al pop dx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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 ASM_END // -------------------------------------------------------------------------------------------- ASM_START 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 seg es mov [bx], al inc bx in al, dx seg es mov [bx], al inc bx in al, dx seg es mov [bx], al inc bx dec cx jnz read_dac_loop pop dx pop cx pop bx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_set_pel_mask: push ax push dx mov dx, # VGAREG_PEL_MASK mov al, bl out dx, al pop dx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_read_pel_mask: push ax push dx mov dx, # VGAREG_PEL_MASK in al, dx mov bl, al pop dx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- ASM_START biosfn_read_video_dac_state: push ax push dx mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x10 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx mov bl, al shr bl, 7 mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x14 out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx mov bh, al and bh, #0x0f test bl, #0x01 jnz get_dac_16_page shr bh, 2 get_dac_16_page: mov dx, # VGAREG_ACTL_RESET in al, dx mov dx, # VGAREG_ACTL_ADDRESS mov al, #0x20 out dx, al pop dx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- static void biosfn_perform_gray_scale_summing (start,count) Bit16u start;Bit16u count; {Bit8u r,g,b; Bit16u i; Bit16u index; inb(VGAREG_ACTL_RESET); outb(VGAREG_ACTL_ADDRESS,0x00); for( index = 0; index < count; index++ ) { // set read address and switch to read mode outb(VGAREG_DAC_READ_ADDRESS,start); // get 6-bit wide RGB data values r=inb( VGAREG_DAC_DATA ); g=inb( VGAREG_DAC_DATA ); b=inb( VGAREG_DAC_DATA ); // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8; if(i>0x3f)i=0x3f; // set write address and switch to write mode outb(VGAREG_DAC_WRITE_ADDRESS,start); // write new intensity value outb( VGAREG_DAC_DATA, i&0xff ); outb( VGAREG_DAC_DATA, i&0xff ); outb( VGAREG_DAC_DATA, i&0xff ); start++; } inb(VGAREG_ACTL_RESET); outb(VGAREG_ACTL_ADDRESS,0x20); } // -------------------------------------------------------------------------------------------- static void get_font_access() { ASM_START mov dx, # VGAREG_SEQU_ADDRESS mov ax, #0x0100 out dx, ax mov ax, #0x0402 out dx, ax mov ax, #0x0704 out dx, ax mov ax, #0x0300 out dx, ax mov dx, # VGAREG_GRDC_ADDRESS mov ax, #0x0204 out dx, ax mov ax, #0x0005 out dx, ax mov ax, #0x0406 out dx, ax ASM_END } static void release_font_access() { ASM_START mov dx, # VGAREG_SEQU_ADDRESS mov ax, #0x0100 out dx, ax mov ax, #0x0302 out dx, ax mov ax, #0x0304 out dx, ax mov ax, #0x0300 out dx, ax mov dx, # VGAREG_READ_MISC_OUTPUT in al, dx and al, #0x01 shl al, 2 or al, #0x0a mov ah, al mov al, #0x06 mov dx, # VGAREG_GRDC_ADDRESS out dx, ax mov ax, #0x0004 out dx, ax mov ax, #0x1005 out dx, ax ASM_END } ASM_START idiv_u: xor dx,dx div bx ret ASM_END static void set_scan_lines(lines) Bit8u lines; { Bit16u crtc_addr,cols,page,vde; Bit8u crtc_r9,ovl,rows; crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); outb(crtc_addr, 0x09); crtc_r9 = inb(crtc_addr+1); crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); outb(crtc_addr+1, crtc_r9); if(lines==8) { biosfn_set_cursor_shape(0x06,0x07); } else { biosfn_set_cursor_shape(lines-4,lines-3); } write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines); outb(crtc_addr, 0x12); vde = inb(crtc_addr+1); outb(crtc_addr, 0x07); ovl = inb(crtc_addr+1); vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); rows = vde / lines; write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1); cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2); } static void biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH) Bit8u AL;Bit16u ES;Bit16u BP;Bit16u CX;Bit16u DX;Bit8u BL;Bit8u BH; { Bit16u blockaddr,dest,i,src; get_font_access(); blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); for(i=0;i=0x10) { set_scan_lines(BH); } } static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL; { Bit16u blockaddr,dest,i,src; get_font_access(); blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); for(i=0;i<0x100;i++) { src = i * 14; dest = blockaddr + i * 32; memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14); } release_font_access(); if(AL>=0x10) { set_scan_lines(14); } } static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL; { Bit16u blockaddr,dest,i,src; get_font_access(); blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); for(i=0;i<0x100;i++) { src = i * 8; dest = blockaddr + i * 32; memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8); } release_font_access(); if(AL>=0x10) { set_scan_lines(8); } } // -------------------------------------------------------------------------------------------- ASM_START biosfn_set_text_block_specifier: push ax push dx mov dx, # VGAREG_SEQU_ADDRESS mov ah, bl mov al, #0x03 out dx, ax pop dx pop ax ret ASM_END // -------------------------------------------------------------------------------------------- static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL; { Bit16u blockaddr,dest,i,src; get_font_access(); blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); for(i=0;i<0x100;i++) { src = i * 16; dest = blockaddr + i * 32; memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16); } release_font_access(); if(AL>=0x10) { set_scan_lines(16); } } static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP; { /* set 0x1F INT pointer */ write_word(0x0, 0x1F*4, BP); write_word(0x0, 0x1F*4+2, ES); write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 8); } static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL; { Bit8u mode; Bit8u line; /* set 0x43 INT pointer */ write_word(0x0, 0x43*4, BP); write_word(0x0, 0x43*4+2, ES); switch (BL) { case 0: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, DL-1); break; case 1: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13); break; case 3: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42); break; case 2: default: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24); break; } write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, CX); } static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL; { /* set 0x43 INT pointer */ write_word(0x0, 0x43*4, &vgafont14); write_word(0x0, 0x43*4+2, 0xC000); switch (BL) { case 1: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13); break; case 3: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42); break; case 2: default: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24); break; } write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 14); } static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL; { /* set 0x43 INT pointer */ write_word(0x0, 0x43*4, &vgafont8); write_word(0x0, 0x43*4+2, 0xC000); switch (BL) { case 1: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13); break; case 3: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42); break; case 2: default: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24); break; } write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 8); } static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL; { /* set 0x43 INT pointer */ write_word(0x0, 0x43*4, &vgafont16); write_word(0x0, 0x43*4+2, 0xC000); switch (BL) { case 1: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13); break; case 3: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42); break; case 2: default: write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24); break; } write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 16); } // -------------------------------------------------------------------------------------------- static void biosfn_get_font_info (BH,ES,BP,CX,DX) Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX; {Bit16u ss=get_SS(); switch(BH) {case 0x00: write_word(ss,ES,read_word(0x00,0x1f*4)); write_word(ss,BP,read_word(0x00,(0x1f*4)+2)); break; case 0x01: write_word(ss,ES,read_word(0x00,0x43*4)); write_word(ss,BP,read_word(0x00,(0x43*4)+2)); break; case 0x02: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont14); break; case 0x03: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont8); break; case 0x04: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont8+128*8); break; case 0x05: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont14alt); break; case 0x06: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont16); break; case 0x07: write_word(ss,ES,0xC000); write_word(ss,BP,vgafont16alt); break; default: #ifdef DEBUG printf("Get font info BH(%02x) was discarded\n",BH); #endif return; } // Set byte/char of on screen font write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); // Set Highest char row write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); } // -------------------------------------------------------------------------------------------- ASM_START 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, #0x0f mov bx, # BIOSMEM_CRTC_ADDRESS mov ax, [bx] mov bx, #0x0003 cmp ax, # VGAREG_MDA_CRTC_ADDRESS jne mode_ega_color mov bh, #0x01 mode_ega_color: pop ax pop ds ret ASM_END // -------------------------------------------------------------------------------------------- static void biosfn_alternate_prtsc() { #ifdef DEBUG unimplemented(); #endif } // -------------------------------------------------------------------------------------------- ASM_START 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, #0x01 je vert_res_350 jb vert_res_200 cmp dl, #0x02 je vert_res_400 #ifdef 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 0x09 and al, #0x7f or al, #0x10 and ah, #0xf0 or ah, #0x09 jnz set_vert_res vert_res_350: ; reset modeset ctl bit 7 and bit 4 ; set switches bit 3-0 to 0x09 and al, #0x6f and ah, #0xf0 or ah, #0x09 jnz set_vert_res vert_res_200: ; set modeset ctl bit 7 and reset bit 4 ; set switches bit 3-0 to 0x08 and al, #0xef or al, #0x80 and ah, #0xf0 or ah, #0x08 set_vert_res: mov bx, # BIOSMEM_MODESET_CTL mov [bx], al mov bx, # BIOSMEM_SWITCHES mov [bx], ah set_retcode: mov ax, #0x1212 pop dx pop bx pop ds ret #ifdef DEBUG msg_vert_res: .ascii "Select vert res (%02x) was discarded" .byte 0x0d,0x0a,0x00 #endif biosfn_enable_default_palette_loading: push ds push bx push dx mov dl, al and dl, #0x01 shl dl, 3 mov ax, # BIOSMEM_SEG mov ds, ax mov bx, # BIOSMEM_MODESET_CTL mov al, [bx] and al, #0xf7 or al, dl mov [bx], al mov ax, #0x1212 pop dx pop bx pop ds ret biosfn_enable_video_addressing: push bx push dx mov bl, al and bl, #0x01 xor bl, #0x01 shl bl, 1 mov dx, # VGAREG_READ_MISC_OUTPUT in al, dx and al, #0xfd or al, bl mov dx, # VGAREG_WRITE_MISC_OUTPUT out dx, al mov ax, #0x1212 pop dx pop bx ret biosfn_enable_grayscale_summing: push ds push bx push dx mov dl, al and dl, #0x01 xor dl, #0x01 shl dl, 1 mov ax, # BIOSMEM_SEG mov ds, ax mov bx, # BIOSMEM_MODESET_CTL mov al, [bx] and al, #0xfd or al, dl mov [bx], al mov ax, #0x1212 pop dx pop bx pop ds ret biosfn_enable_cursor_emulation: push ds push bx push dx mov dl, al and dl, #0x01 xor dl, #0x01 mov ax, # BIOSMEM_SEG mov ds, ax mov bx, # BIOSMEM_MODESET_CTL mov al, [bx] and al, #0xfe or al, dl mov [bx], al mov ax, #0x1212 pop dx pop bx pop ds ret ASM_END // -------------------------------------------------------------------------------------------- static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX; { #ifdef DEBUG unimplemented(); #endif } static void biosfn_enable_video_refresh_control (AL) Bit8u AL; { #ifdef DEBUG unimplemented(); #endif } // -------------------------------------------------------------------------------------------- static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset; { Bit16u newcurs,oldcurs,dummy; Bit8u car,carattr; // Read curs info for the page biosfn_get_cursor_pos(page,&dummy,&oldcurs); // if row=0xff special case : use current cursor position if(row==0xff) {col=oldcurs&0x00ff; row=(oldcurs&0xff00)>>8; } newcurs=row; newcurs<<=8; newcurs+=col; biosfn_set_cursor_pos(page,newcurs); while(count--!=0) { car=read_byte(seg,offset++); if((flag&0x02)!=0) attr=read_byte(seg,offset++); biosfn_write_teletype(car,page,attr,WITH_ATTR); } // Set back curs pos if((flag&0x01)==0) biosfn_set_cursor_pos(page,oldcurs); } // -------------------------------------------------------------------------------------------- ASM_START biosfn_group_1A: cmp al, #0x00 je biosfn_read_display_code cmp al, #0x01 je biosfn_set_display_code #ifdef 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 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 DEBUG msg_alt_dcc: .ascii "Alternate Display code (%02x) was discarded" .byte 0x0d,0x0a,0x00 #endif ASM_END // -------------------------------------------------------------------------------------------- static void biosfn_read_state_info (BX,ES,DI) Bit16u BX;Bit16u ES;Bit16u DI; { // Address of static functionality table write_word(ES,DI+0x00,&static_functionality); write_word(ES,DI+0x02,0xC000); // Hard coded copy from BIOS area. Should it be cleaner ? memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30); memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3); write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); write_byte(ES,DI+0x26,0); write_byte(ES,DI+0x27,16); write_byte(ES,DI+0x28,0); write_byte(ES,DI+0x29,8); write_byte(ES,DI+0x2a,2); write_byte(ES,DI+0x2b,0); write_byte(ES,DI+0x2c,0); write_byte(ES,DI+0x31,3); write_byte(ES,DI+0x32,0); memsetb(ES,DI+0x33,0,13); } // -------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------- static Bit16u biosfn_read_video_state_size2 (CX) Bit16u CX; { Bit16u size; size = 0; if (CX & 1) { size += 0x46; } if (CX & 2) { size += (5 + 8 + 5) * 2 + 6; } if (CX & 4) { size += 3 + 256 * 3 + 1; } return size; } static void biosfn_read_video_state_size (CX, BX) Bit16u CX; Bit16u *BX; { Bit16u ss=get_SS(); write_word(ss, BX, biosfn_read_video_state_size2(CX)); } static Bit16u biosfn_save_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX; { Bit16u i, v, crtc_addr, ar_index; crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS); if (CX & 1) { write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++; write_byte(ES, BX, inb(crtc_addr)); BX++; write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++; inb(VGAREG_ACTL_RESET); ar_index = inb(VGAREG_ACTL_ADDRESS); write_byte(ES, BX, ar_index); BX++; write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++; for(i=1;i<=4;i++){ outb(VGAREG_SEQU_ADDRESS, i); write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; } outb(VGAREG_SEQU_ADDRESS, 0); write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; for(i=0;i<=0x18;i++) { outb(crtc_addr,i); write_byte(ES, BX, inb(crtc_addr+1)); BX++; } for(i=0;i<=0x13;i++) { inb(VGAREG_ACTL_RESET); outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++; } inb(VGAREG_ACTL_RESET); for(i=0;i<=8;i++) { outb(VGAREG_GRDC_ADDRESS,i); write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++; } write_word(ES, BX, crtc_addr); BX+= 2; /* XXX: read plane latches */ write_byte(ES, BX, 0); BX++; write_byte(ES, BX, 0); BX++; write_byte(ES, BX, 0); BX++; write_byte(ES, BX, 0); BX++; } if (CX & 2) { write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++; write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2; write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2; write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2; write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++; write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2; write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++; write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++; write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++; write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2; for(i=0;i<8;i++) { write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i)); BX += 2; } write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2; write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++; /* current font */ write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2; write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2; write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2; write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2; } if (CX & 4) { /* XXX: check this */ write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */ write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */ write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++; // Set the whole dac always, from 0 outb(VGAREG_DAC_WRITE_ADDRESS,0x00); for(i=0;i<256*3;i++) { write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++; } write_byte(ES, BX, 0); BX++; /* color select register */ } return BX; } static Bit16u biosfn_restore_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX; { Bit16u i, crtc_addr, v, addr1, ar_index; if (CX & 1) { // Reset Attribute Ctl flip-flop inb(VGAREG_ACTL_RESET); crtc_addr = read_word(ES, BX + 0x40); addr1 = BX; BX += 5; for(i=1;i<=4;i++){ outb(VGAREG_SEQU_ADDRESS, i); outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; } outb(VGAREG_SEQU_ADDRESS, 0); outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; // Disable CRTC write protection outw(crtc_addr,0x0011); // Set CRTC regs for(i=0;i<=0x18;i++) { if (i != 0x11) { outb(crtc_addr,i); outb(crtc_addr+1, read_byte(ES, BX)); } BX++; } // select crtc base address v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; if (crtc_addr = 0x3d4) v |= 0x01; outb(VGAREG_WRITE_MISC_OUTPUT, v); // enable write protection if needed outb(crtc_addr, 0x11); outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11)); // Set Attribute Ctl ar_index = read_byte(ES, addr1 + 0x03); inb(VGAREG_ACTL_RESET); for(i=0;i<=0x13;i++) { outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++; } outb(VGAREG_ACTL_ADDRESS, ar_index); inb(VGAREG_ACTL_RESET); for(i=0;i<=8;i++) { outb(VGAREG_GRDC_ADDRESS,i); outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++; } BX += 2; /* crtc_addr */ BX += 4; /* plane latches */ outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++; outb(crtc_addr, read_byte(ES, addr1)); addr1++; outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++; addr1++; outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++; } if (CX & 2) { write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++; write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2; write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2; write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2; write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++; write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2; write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++; write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++; write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++; write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2; for(i=0;i<8;i++) { write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX)); BX += 2; } write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2; write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++; /* current font */ write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2; write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2; write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2; write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2; } if (CX & 4) { BX++; v = read_byte(ES, BX); BX++; outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++; // Set the whole dac always, from 0 outb(VGAREG_DAC_WRITE_ADDRESS,0x00); for(i=0;i<256*3;i++) { outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++; } BX++; outb(VGAREG_DAC_WRITE_ADDRESS, v); } return BX; } // ============================================================================================ // // Video Utils // // ============================================================================================ // -------------------------------------------------------------------------------------------- static Bit8u find_vga_entry(mode) Bit8u mode; { Bit8u i,line=0xFF; for(i=0;i<=MODE_MAX;i++) if(vga_modes[i].svgamode==mode) {line=i; break; } return line; } /* =========================================================== */ /* * Misc Utils */ /* =========================================================== */ // -------------------------------------------------------------------------------------------- static void memsetb(seg,offset,value,count) Bit16u seg; Bit16u offset; Bit16u value; Bit16u count; { ASM_START push bp mov bp, sp push ax push cx push es push di mov cx, 10[bp] ; count cmp cx, #0x00 je memsetb_end mov ax, 4[bp] ; segment mov es, ax mov ax, 6[bp] ; offset mov di, ax mov al, 8[bp] ; value cld rep stosb memsetb_end: pop di pop es pop cx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- static void memsetw(seg,offset,value,count) Bit16u seg; Bit16u offset; Bit16u value; Bit16u count; { ASM_START push bp mov bp, sp push ax push cx push es push di mov cx, 10[bp] ; count cmp cx, #0x00 je memsetw_end mov ax, 4[bp] ; segment mov es, ax mov ax, 6[bp] ; offset mov di, ax mov ax, 8[bp] ; value cld rep stosw memsetw_end: pop di pop es pop cx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- static void memcpyb(dseg,doffset,sseg,soffset,count) Bit16u dseg; Bit16u doffset; Bit16u sseg; Bit16u soffset; Bit16u count; { ASM_START push bp mov bp, sp push ax push cx push es push di push ds push si mov cx, 12[bp] ; count cmp cx, #0x0000 je memcpyb_end mov ax, 4[bp] ; dsegment mov es, ax mov ax, 6[bp] ; doffset mov di, ax mov ax, 8[bp] ; ssegment mov ds, ax mov ax, 10[bp] ; soffset mov si, ax cld rep movsb memcpyb_end: pop si pop ds pop di pop es pop cx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- static void memcpyw(dseg,doffset,sseg,soffset,count) Bit16u dseg; Bit16u doffset; Bit16u sseg; Bit16u soffset; Bit16u count; { ASM_START push bp mov bp, sp push ax push cx push es push di push ds push si mov cx, 12[bp] ; count cmp cx, #0x0000 je memcpyw_end mov ax, 4[bp] ; dsegment mov es, ax mov ax, 6[bp] ; doffset mov di, ax mov ax, 8[bp] ; ssegment mov ds, ax mov ax, 10[bp] ; soffset mov si, ax cld rep movsw memcpyw_end: pop si pop ds pop di pop es pop cx pop ax pop bp ASM_END } /* =========================================================== */ /* * These functions where ripped from Kevin's rombios.c */ /* =========================================================== */ // -------------------------------------------------------------------------------------------- static Bit8u read_byte(seg, offset) Bit16u seg; Bit16u offset; { ASM_START push bp mov bp, sp push bx push ds mov ax, 4[bp] ; segment mov ds, ax mov bx, 6[bp] ; offset mov al, [bx] ;; al = return value (byte) pop ds pop bx pop bp ASM_END } // -------------------------------------------------------------------------------------------- static Bit16u read_word(seg, offset) Bit16u seg; Bit16u offset; { ASM_START push bp mov bp, sp push bx push ds mov ax, 4[bp] ; segment mov ds, ax mov bx, 6[bp] ; offset mov ax, [bx] ;; ax = return value (word) pop ds pop bx pop bp ASM_END } // -------------------------------------------------------------------------------------------- static void write_byte(seg, offset, data) Bit16u seg; Bit16u offset; Bit8u data; { ASM_START push bp mov bp, sp push ax push bx push ds mov ax, 4[bp] ; segment mov ds, ax mov bx, 6[bp] ; offset mov al, 8[bp] ; data byte mov [bx], al ; write data byte pop ds pop bx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- static void write_word(seg, offset, data) Bit16u seg; Bit16u offset; Bit16u data; { ASM_START push bp mov bp, sp push ax push bx push ds mov ax, 4[bp] ; segment mov ds, ax mov bx, 6[bp] ; offset mov ax, 8[bp] ; data word mov [bx], ax ; write data word pop ds pop bx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- Bit8u inb(port) Bit16u port; { ASM_START push bp mov bp, sp push dx mov dx, 4[bp] in al, dx pop dx pop bp ASM_END } Bit16u inw(port) Bit16u port; { ASM_START push bp mov bp, sp push dx mov dx, 4[bp] in ax, dx pop dx pop bp ASM_END } // -------------------------------------------------------------------------------------------- void outb(port, val) Bit16u port; Bit8u val; { ASM_START push bp mov bp, sp push ax push dx mov dx, 4[bp] mov al, 6[bp] out dx, al pop dx pop ax pop bp ASM_END } // -------------------------------------------------------------------------------------------- void outw(port, val) Bit16u port; Bit16u val; { ASM_START push bp mov bp, sp push ax push dx mov dx, 4[bp] mov ax, 6[bp] out dx, ax pop dx pop ax pop bp ASM_END } Bit16u get_SS() { ASM_START mov ax, ss ASM_END } #ifdef DEBUG void unimplemented() { printf("--> Unimplemented\n"); } void unknown() { printf("--> Unknown int10\n"); } #endif // -------------------------------------------------------------------------------------------- #if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG) void printf(s) Bit8u *s; { Bit8u c, format_char; Boolean in_format; unsigned format_width, i; Bit16u *arg_ptr; Bit16u arg_seg, arg, digit, nibble, shift_count; arg_ptr = &s; arg_seg = get_SS(); in_format = 0; format_width = 0; while (c = read_byte(0xc000, s)) { if ( c == '%' ) { in_format = 1; format_width = 0; } else if (in_format) { if ( (c>='0') && (c<='9') ) { format_width = (format_width * 10) + (c - '0'); } else if (c == 'x') { arg_ptr++; // increment to next arg arg = read_word(arg_seg, arg_ptr); if (format_width == 0) format_width = 4; i = 0; digit = format_width - 1; for (i=0; i> (4 * digit)) & 0x000f; if (nibble <= 9) outb(0x0500, nibble + '0'); else outb(0x0500, (nibble - 10) + 'A'); digit--; } in_format = 0; } //else if (c == 'd') { // in_format = 0; // } } else { outb(0x0500, c); } s ++; } } #endif ASM_START ; get LFB address from PCI ; in - ax: PCI device vendor ; out - ax: LFB address (high 16 bit) ;; NOTE - may be called in protected mode _pci_get_lfb_addr: push bx push cx push dx push eax mov bx, ax xor cx, cx mov dl, #0x00 call pci_read_reg cmp ax, #0xffff jz pci_get_lfb_addr_fail pci_get_lfb_addr_next_dev: mov dl, #0x00 call pci_read_reg cmp ax, bx ;; check vendor jz pci_get_lfb_addr_found add cx, #0x8 cmp cx, #0x200 ;; search bus #0 and #1 jb pci_get_lfb_addr_next_dev pci_get_lfb_addr_fail: xor dx, dx ;; no LFB jmp pci_get_lfb_addr_return pci_get_lfb_addr_found: mov dl, #0x10 ;; I/O space #0 call pci_read_reg test ax, #0xfff1 jz pci_get_lfb_addr_success mov dl, #0x14 ;; I/O space #1 call pci_read_reg test ax, #0xfff1 jnz pci_get_lfb_addr_fail pci_get_lfb_addr_success: shr eax, #16 mov dx, ax ;; LFB address pci_get_lfb_addr_return: pop eax mov ax, dx pop dx pop cx pop bx ret ; read PCI register ; in - cx: device/function ; in - dl: register ; out - eax: value pci_read_reg: mov eax, #0x00800000 mov ax, cx shl eax, #8 mov al, dl mov dx, #0xcf8 out dx, eax add dl, #4 in eax, dx ret ASM_END #ifdef VBE #include "vbe.c" #endif #ifdef CIRRUS #include "clext.c" #endif // -------------------------------------------------------------------------------------------- ASM_START ;; DATA_SEG_DEFS_HERE ASM_END ASM_START .ascii "vgabios ends here" .byte 0x00 vgabios_end: .byte 0xCB ;; BLOCK_STRINGS_BEGIN ASM_END vgabios-0.7a/vgabios.h0000644000175000017500000000253507542435636014657 0ustar guillemguillem#ifndef vgabios_h_included #define vgabios_h_included /* Types */ typedef unsigned char Bit8u; typedef unsigned short Bit16u; typedef unsigned long Bit32u; typedef unsigned short Boolean; /* Defines */ #define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) #define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) #define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) #define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) #define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) #define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) #define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) #define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) #define GET_AL() ( AX & 0x00ff ) #define GET_BL() ( BX & 0x00ff ) #define GET_CL() ( CX & 0x00ff ) #define GET_DL() ( DX & 0x00ff ) #define GET_AH() ( AX >> 8 ) #define GET_BH() ( BX >> 8 ) #define GET_CH() ( CX >> 8 ) #define GET_DH() ( DX >> 8 ) #define SET_CF() FLAGS |= 0x0001 #define CLEAR_CF() FLAGS &= 0xfffe #define GET_CF() (FLAGS & 0x0001) #define SET_ZF() FLAGS |= 0x0040 #define CLEAR_ZF() FLAGS &= 0xffbf #define GET_ZF() (FLAGS & 0x0040) #define SCROLL_DOWN 0 #define SCROLL_UP 1 #define NO_ATTR 2 #define WITH_ATTR 3 #define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) #define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) #define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) #endif vgabios-0.7a/.cvsignore0000644000175000017500000000001410467304316015030 0ustar guillemguillemvbetables.h vgabios-0.7a/vbetables-gen.c0000644000175000017500000002344611521570432015724 0ustar guillemguillem/* Generate the VGABIOS VBE Tables */ #include #include #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16 typedef struct { int width; int height; int depth; int mode; } ModeInfo; ModeInfo modes[] = { /* standard VESA modes */ { 640, 400, 8 , 0x100}, { 640, 480, 8 , 0x101}, { 800, 600, 4 , 0x102}, { 800, 600, 8 , 0x103}, { 1024, 768, 4 , 0x104}, { 1024, 768, 8 , 0x105}, { 1280, 1024, 4 , 0x106}, { 1280, 1024, 8 , 0x107}, { 320, 200, 15 , 0x10D}, { 320, 200, 16 , 0x10E}, { 320, 200, 24 , 0x10F}, { 640, 480, 15 , 0x110}, { 640, 480, 16 , 0x111}, { 640, 480, 24 , 0x112}, { 800, 600, 15 , 0x113}, { 800, 600, 16 , 0x114}, { 800, 600, 24 , 0x115}, { 1024, 768, 15 , 0x116}, { 1024, 768, 16 , 0x117}, { 1024, 768, 24 , 0x118}, { 1280, 1024, 15 , 0x119}, { 1280, 1024, 16 , 0x11A}, { 1280, 1024, 24 , 0x11B}, { 1600, 1200, 8 , 0x11C}, { 1600, 1200, 15 , 0x11D}, { 1600, 1200, 16 , 0x11E}, { 1600, 1200, 24 , 0x11F}, /* BOCHS/PLEX86 'own' mode numbers */ { 320, 200, 32 , 0x140}, { 640, 400, 32 , 0x141}, { 640, 480, 32 , 0x142}, { 800, 600, 32 , 0x143}, { 1024, 768, 32 , 0x144}, { 1280, 1024, 32 , 0x145}, { 320, 200, 8 , 0x146}, { 1600, 1200, 32 , 0x147}, { 1152, 864, 8 , 0x148}, { 1152, 864, 15 , 0x149}, { 1152, 864, 16 , 0x14a}, { 1152, 864, 24 , 0x14b}, { 1152, 864, 32 , 0x14c}, { 1280, 768, 16 , 0x175}, { 1280, 768, 24 , 0x176}, { 1280, 768, 32 , 0x177}, { 1280, 800, 16 , 0x178}, { 1280, 800, 24 , 0x179}, { 1280, 800, 32 , 0x17a}, { 1280, 960, 16 , 0x17b}, { 1280, 960, 24 , 0x17c}, { 1280, 960, 32 , 0x17d}, { 1440, 900, 16 , 0x17e}, { 1440, 900, 24 , 0x17f}, { 1440, 900, 32 , 0x180}, { 1400, 1050, 16 , 0x181}, { 1400, 1050, 24 , 0x182}, { 1400, 1050, 32 , 0x183}, { 1680, 1050, 16 , 0x184}, { 1680, 1050, 24 , 0x185}, { 1680, 1050, 32 , 0x186}, { 1920, 1200, 16 , 0x187}, { 1920, 1200, 24 , 0x188}, { 1920, 1200, 32 , 0x189}, { 2560, 1600, 16 , 0x18a}, { 2560, 1600, 24 , 0x18b}, { 2560, 1600, 32 , 0x18c}, { 1280, 720, 16 , 0x18d}, { 1280, 720, 24 , 0x18e}, { 1280, 720, 32 , 0x18f}, { 1920, 1080, 16 , 0x190}, { 1920, 1080, 24 , 0x191}, { 1920, 1080, 32 , 0x192}, { 0, }, }; int main(int argc, char **argv) { const ModeInfo *pm; int pages, pitch; int r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; const char *str; long vram_size = VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024 * 1024; printf("/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); printf("#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB %d\n\n", VBE_DISPI_TOTAL_VIDEO_MEMORY_MB); printf("static ModeInfoListItem mode_info_list[]=\n"); printf("{\n"); for (pm = modes; pm->mode != 0; pm++) { if (pm->depth == 4) pitch = (pm->width + 7) / 8; else pitch = pm->width * ((pm->depth + 7) / 8); pages = vram_size / (pm->height * pitch); if (pages > 0) { printf("{ 0x%04x, /* %dx%dx%d */\n", pm->mode, pm->width, pm->height, pm->depth); if (pm->depth == 4) printf("{ /*Bit16u ModeAttributes*/ %s,\n", "VBE_MODE_ATTRIBUTE_SUPPORTED | " "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " "VBE_MODE_ATTRIBUTE_COLOR_MODE | " "VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT | " "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); else printf("{ /*Bit16u ModeAttributes*/ %s,\n", "VBE_MODE_ATTRIBUTE_SUPPORTED | " "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " "VBE_MODE_ATTRIBUTE_COLOR_MODE | " "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | " "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); printf("/*Bit8u WinAAttributes*/ %s,\n", "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | " "VBE_WINDOW_ATTRIBUTE_READABLE | " "VBE_WINDOW_ATTRIBUTE_WRITEABLE"); printf("/*Bit8u WinBAttributes*/ %d,\n", 0); printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH"); printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0); printf("/*Bit32u WinFuncPtr*/ %d,\n", 0); printf("/*Bit16u BytesPerScanLine*/ %d,\n", pitch); // Mandatory information for VBE 1.2 and above printf("/*Bit16u XResolution*/ %d,\n", pm->width); printf("/*Bit16u YResolution*/ %d,\n", pm->height); printf("/*Bit8u XCharSize*/ %d,\n", 8); printf("/*Bit8u YCharSize*/ %d,\n", 16); if (pm->depth == 4) { printf("/*Bit8u NumberOfPlanes*/ %d,\n", 4); } else { printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1); } printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth); printf("/*Bit8u NumberOfBanks*/ %d,\n", (pm->height * pitch + 65535) / 65536); if (pm->depth == 4) str = "VBE_MEMORYMODEL_PLANAR"; else if (pm->depth == 8) str = "VBE_MEMORYMODEL_PACKED_PIXEL"; else str = "VBE_MEMORYMODEL_DIRECT_COLOR"; printf("/*Bit8u MemoryModel*/ %s,\n", str); printf("/*Bit8u BankSize*/ %d,\n", 0); if (pm->depth == 4) printf("/*Bit8u NumberOfImagePages*/ %d,\n", (pages / 4) - 1); else printf("/*Bit8u NumberOfImagePages*/ %d,\n", pages - 1); printf("/*Bit8u Reserved_page*/ %d,\n", 0); // Direct Color fields (required for direct/6 and YUV/7 memory models) switch(pm->depth) { case 15: r_size = 5; r_pos = 10; g_size = 5; g_pos = 5; b_size = 5; b_pos = 0; a_size = 1; a_pos = 15; break; case 16: r_size = 5; r_pos = 11; g_size = 6; g_pos = 5; b_size = 5; b_pos = 0; a_size = 0; a_pos = 0; break; case 24: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; b_size = 8; b_pos = 0; a_size = 0; a_pos = 0; break; case 32: r_size = 8; r_pos = 16; g_size = 8; g_pos = 8; b_size = 8; b_pos = 0; a_size = 8; a_pos = 24; break; default: r_size = 0; r_pos = 0; g_size = 0; g_pos = 0; b_size = 0; b_pos = 0; a_size = 0; a_pos = 0; break; } printf("/*Bit8u RedMaskSize*/ %d,\n", r_size); printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos); printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size); printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos); printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size); printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos); printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size); printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos); if (pm->depth == 32) printf("/*Bit8u DirectColorModeInfo*/ %s,\n", "VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE"); else printf("/*Bit8u DirectColorModeInfo*/ %s,\n", "0"); // Mandatory information for VBE 2.0 and above if (pm->depth > 4) printf("/*Bit32u PhysBasePtr*/ %s,\n", "VBE_DISPI_LFB_PHYSICAL_ADDRESS"); else printf("/*Bit32u PhysBasePtr*/ %s,\n", "0"); printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0); printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0); // Mandatory information for VBE 3.0 and above printf("/*Bit16u LinBytesPerScanLine*/ %d,\n", pitch); printf("/*Bit8u BnkNumberOfPages*/ %d,\n", 0); printf("/*Bit8u LinNumberOfPages*/ %d,\n", 0); printf("/*Bit8u LinRedMaskSize*/ %d,\n", r_size); printf("/*Bit8u LinRedFieldPosition*/ %d,\n", r_pos); printf("/*Bit8u LinGreenMaskSize*/ %d,\n", g_size); printf("/*Bit8u LinGreenFieldPosition*/ %d,\n", g_pos); printf("/*Bit8u LinBlueMaskSize*/ %d,\n", b_size); printf("/*Bit8u LinBlueFieldPosition*/ %d,\n", b_pos); printf("/*Bit8u LinRsvdMaskSize*/ %d,\n", a_size); printf("/*Bit8u LinRsvdFieldPosition*/ %d,\n", a_pos); printf("/*Bit32u MaxPixelClock*/ %d,\n", 0); printf("} },\n"); } } printf("{ VBE_VESA_MODE_END_OF_LIST,\n"); printf("{ 0,\n"); printf("} },\n"); printf("};\n"); return 0; } vgabios-0.7a/Notes0000644000175000017500000000045707434154024014055 0ustar guillemguillemDevelopment notes ----------------- - need to split video init function 1. set bios variables 2. do the real init with io based on bios variables - characters format switching will set the bios variables and call function #2 above - need to rework the tables as explained in Interrupt list vgabios-0.7a/vbe_display_api.txt0000644000175000017500000002264510746607545016753 0ustar guillemguillemVBE Display API ------------------------------------------------------------------------------------------------------------- This document is part of the Bochs/VBEBios documentation, it specifies the bochs host <-> vbebios client communication. That means, the display code implementation and the vbebios code depend very heavily on each other. As such, this documents needs be synchronised between bochs CVS and the vgabios CVS. This document does not describe how the VBEBios implements the VBE2/3 spec. This document does not describe how the Bochs display code will display gfx based upon this spec. API History ----------- 0xb0c0 supports the following VBE_DISPI_ interfaces (present in Bochs 1.4): VBE_DISPI_INDEX_ID VBE_DISPI_INDEX_XRES VBE_DISPI_INDEX_YRES VBE_DISPI_INDEX_BPP VBE_DISPI_INDEX_ENABLE VBE_DISPI_INDEX_BANK Bpp format supported is: VBE_DISPI_BPP_8 0xb0c1 supports 0xb0c0 VBE_DISPI_ interfaces, additional interfaces (present in Bochs 2.0): VBE_DISPI_INDEX_VIRT_WIDTH VBE_DISPI_INDEX_VIRT_HEIGHT VBE_DISPI_INDEX_X_OFFSET VBE_DISPI_INDEX_Y_OFFSET 0xb0c2 supports 0xb0c1 VBE_DISPI_ interfaces, interfaces updated for additional features (present in Bochs 2.1): VBE_DISPI_INDEX_BPP supports >8bpp color depth (value = bits) VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_NOCLEARMEM and VBE_DISPI_LFB_ENABLED VBE i/o registers changed from 0xFF80/81 to 0x01CE/CF 0xb0c3 supports 0xb0c2 VBE_DISPI_ interfaces, interfaces updated for additional features: VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_GETCAPS and VBE_DISPI_8BIT_DAC 0xb0c4 VBE video memory increased to 8 MB History ------- Version 0.6 2002 Nov 23 Jeroen Janssen - Added LFB support - Added Virt width, height and x,y offset Version 0.5 2002 March 08 Jeroen Janssen - Added documentation about panic behaviour / current limits of the data values. - Changed BPP API (in order to include future (A)RGB formats) - Initial version (based upon extended display text of the vbe bochs display patch) Todo ---- Version 0.6+ [random order] - Add lots of different (A)RGB formats References ---------- [VBE3] VBE 3 Specification at http://www.vesa.org/vbe3.pdf [BOCHS] Bochs Open Source IA-32 Emulator at http://bochs.sourceforge.net [VBEBIOS] VBE Bios for Bochs at http://savannah.gnu.org/projects/vgabios/ [Screenshots] Screenshots of programs using the VBE Bios at http://japj.org/projects/bochs_plex86/screenshots.html Abbreviations ------------- VBE Vesa Bios Extension DISPI (Bochs) Display Interface BPP Bits Per Pixel LFB Linear Frame Buffer #defines -------- vbetables-gen.c #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8 vbe.h #define VBE_DISPI_BANK_ADDRESS 0xA0000 #define VBE_DISPI_BANK_SIZE_KB 64 #define VBE_DISPI_MAX_XRES 1024 #define VBE_DISPI_MAX_YRES 768 #define VBE_DISPI_IOPORT_INDEX 0x01CE #define VBE_DISPI_IOPORT_DATA 0x01CF #define VBE_DISPI_INDEX_ID 0x0 #define VBE_DISPI_INDEX_XRES 0x1 #define VBE_DISPI_INDEX_YRES 0x2 #define VBE_DISPI_INDEX_BPP 0x3 #define VBE_DISPI_INDEX_ENABLE 0x4 #define VBE_DISPI_INDEX_BANK 0x5 #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 #define VBE_DISPI_INDEX_X_OFFSET 0x8 #define VBE_DISPI_INDEX_Y_OFFSET 0x9 #define VBE_DISPI_ID0 0xB0C0 #define VBE_DISPI_ID1 0xB0C1 #define VBE_DISPI_ID2 0xB0C2 #define VBE_DISPI_ID3 0xB0C3 #define VBE_DISPI_ID4 0xB0C4 #define VBE_DISPI_DISABLED 0x00 #define VBE_DISPI_ENABLED 0x01 #define VBE_DISPI_VBE_ENABLED 0x40 #define VBE_DISPI_NOCLEARMEM 0x80 #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 API --- The display api works by using a index (VBE_DISPI_IOPORT_INDEX) and data (VBE_DISPI_IOPORT_DATA) ioport. One writes the index of the parameter to the index port. Next, the parameter value can be read or written. [0xb0c0] * VBE_DISPI_INDEX_ID : WORD {R,W} This parameter can be used to detect the current display API (both bochs & vbebios). The bios writes VBE_DISPI_ID0 to the dataport and reads it back again. This way, the display code knows the vbebios 'ID' and the vbebios can check if the correct display code is present. As a result, a PANIC can be generated if an incompatible vbebios/display code combination is detected. This panic can be generated from the bochs display code (NOT the bios, see Notes). Example values: VBE_DISPI_ID0 * VBE_DISPI_INDEX_XRES : WORD {R,W} This parameter can be used to read/write the vbe display X resolution (in pixels). It's illegal to set the XRES when the VBE is enabled (display code should generate PANIC). If the value written exceeds VBE_DISPI_MAX_XRES, the display code needs to generate a PANIC. Example values: 320,640,800,1024 * VBE_DISPI_INDEX_YRES : WORD {R,W} This parameter can be used to read/write the vbe display Y resolution (in pixels). It's illegal to set the YRES when the VBE is enabled (display code should generate PANIC). If the value written exceeds VBE_DISPI_MAX_YRES, the display code needs to generate a PANIC. Example values: 200,400,480,600,768 * VBE_DISPI_INDEX_BPP : WORD {R,W} This parameter can be used to read/write the vbe display BPP. It's illegal to set the BPP when the VBE is enabled (display code should generate PANIC). If the value written is an incompatible BPP, the display code needs to generate a PANIC. Example values: VBE_DISPI_BPP_8 * VBE_DISPI_INDEX_ENABLE : WORD {R,W} This parameter can be used to read/write the vbe ENABLED state. If the bios writes VBE_DISPI_ENABLED then the display code will setup a hostside display mode with the current XRES, YRES and BPP settings. If the bios write VBE_DISPI_DISABLED then the display code will switch back to normal vga mode behaviour. Example values: VBE_DISPI_ENABLED, VBE_DISPI_DISABLED * VBE_DISPI_INDEX_BANK : WORD {R,W} This parameter can be used to read/write the current selected BANK (at 0xA0000). This can be used for switching banks in banked mode. [0xb0c1] * VBE_DISPI_INDEX_VIRT_WIDTH : WORD {R,W} This parameter can be used to read/write the current virtual width. Upon enabling a mode, this will be set to the current xres Setting this field during enabled mode will result in the virtual width to be changed. Value will be adjusted if current setting is not possible. * VBE_DISPI_INDEX_VIRT_HEIGHT : WORD {R} This parameter can be read in order to obtain the current virtual height. This setting will be adjusted after setting a virtual width in order to stay within limit of video memory. * VBE_DISPI_INDEX_X_OFFSET : WORD {R,W} The current X offset (in pixels!) of the visible screen part. Writing a new offset will also result in a complete screen refresh. * VBE_DISPI_INDEX_Y_OFFSET : WORD {R,W} The current Y offset (in pixels!) of the visible screen part. Writing a new offset will also result in a complete screen refresh. [0xb0c2] * VBE_DISPI_INDEX_BPP : WORD {R,W} The value written is now the number of bits per pixel. A value of 0 is treated the same as 8 for backward compatibilty. These values are supported: 8, 15, 16, 24 and 32. The value of 4 is not yet handled in the VBE code. * VBE_DISPI_INDEX_ENABLE : WORD {R,W} The new flag VBE_DISPI_NOCLEARMEM allows to preserve the VBE video memory. The new flag VBE_DISPI_LFB_ENABLED indicates the usage of the LFB. [0xb0c3] * VBE_DISPI_INDEX_ENABLE : WORD {R,W} If the new flag VBE_DISPI_GETCAPS is enabled, the xres, yres and bpp registers return the gui capabilities. The new flag VBE_DISPI_8BIT_DAC switches the DAC to 8 bit mode. [0xb0c4] * VBE_DISPI_TOTAL_VIDEO_MEMORY_MB set to 8 (moved to auto-generated vbetables.h) Displaying GFX (banked mode) -------------- What happens is that the total screen is devided in banks of 'VBE_DISPI_BANK_SIZE_KB' KiloByte in size. If you want to set a pixel you can calculate its bank by doing: offset = pixel_x + pixel_y * resolution_x; bank = offset / 64 Kb (rounded 1.9999 -> 1) bank_pixel_pos = offset - bank * 64Kb Now you can set the current bank and put the pixel at VBE_DISPI_BANK_ADDRESS + bank_pixel_pos Displaying GFX (linear frame buffer mode) -------------- NOT WRITTEN YET Notes ----- * Since the XRES/YRES/BPP may not be written when VBE is enabled, if you want to switch from one VBE mode to another, you will need to disable VBE first. * Note when the bios doesn't find a valid DISPI_ID, it can disable the VBE functions. This allows people to use the same bios for both vbe enabled and disabled bochs executables. vgabios-0.7a/ChangeLog0000644000175000017500000011141211653242216014605 0ustar guillemguillem2011-10-15 16:07 vruppert * vgabios.c (1.75): - implemented vgabios functions with AX=0x112x (patch by Hugo Mercier) 2011-07-19 22:17 vruppert * vgabios.c (1.74): - update pci_get_lfb_addr for vmware vga (patch by Gerd Hoffmann) - pci_get_lfb_addr now checks BAR #1 too - give names to the numbered labels to make the code more readable 2011-07-19 20:25 vruppert * vbe.c (1.64), vgabios.c (1.73): - VBE: added support for setting PCI vendor and device IDs using defines (PCI_VID and PCI_DID). Based on a patch by Gerd Hoffmann. 2011-07-19 19:00 vruppert * Makefile (1.23): - Makefile cleanup patch by Gerd Hoffmann - use a single rule for building bios binaries - use target specific variables to set compile flags This makes it more obvious what the differences between the versions are. It also makes it easier to add new bios binaries with slightly different settings. 2011-06-27 19:58 vruppert * Makefile (1.22), vgabios.c (1.72): - added PCI ROM support to the VBE-specific images 2011-04-14 18:10 vruppert * clext.c (1.15), vbe.c (1.63), vgabios.c (1.71): - fixed DAC palette in 8 bpp VBE and Cirrus modes (using the same palette as VGA mode 0x13) 2011-01-31 18:28 vruppert * vbetables-gen.c (1.6): - added HDTV resolutions (patch by Tristan Schmelcher) 2011-01-29 09:42 vruppert * vgabios.c (1.70): - fixed vgabios init with logging disabled 2009-04-07 20:18 vruppert * vgabios.c (1.69): - biosfn_write_teletype: fixed attribute when scrolling in text mode 2009-04-06 20:17 vruppert * ChangeLog (1.28), README (1.17): - preparing for release 0.6c 2009-01-25 16:46 vruppert * vbe.c (1.62), vbe.h (1.28), vbetables-gen.c (1.5): - added support for a lot more non-standard VBE modes (e.g. widescreen modes) - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size in 64k pages stored in VBE register) - check if VBE mode is supported with current VRAM size 2009-01-24 11:02 vruppert * clext.c (1.14), vbe.c (1.61), vgabios.c (1.68): - use VBE LFB address from PCI base address if present (rewrite of the cirrus specific function in main vgabios code) - removed unnecessary spaces 2008-12-14 09:29 vruppert * clext.c (1.13): - added DPMS support to cirrus vgabios (patch from Gleb Natapov) 2008-05-30 17:28 vruppert * README (1.16): - updated for release 0.6b 2008-05-22 12:55 vruppert * ChangeLog (1.27), README (1.15): - preparations for release 0.6b 2008-05-11 08:40 vruppert * biossums.c (1.6): - fixed a warning 2008-03-02 08:47 vruppert * vbe.c (1.60): - added debug message for unsupported VBE modes 2008-02-24 09:18 vruppert * vbe.c (1.59): - in LFB modes the number of banks must be set to 1 2008-01-27 10:44 vruppert * Makefile (1.21), biossums.c (1.5), vgabios.c (1.67): - added PCI data structure for the Cirrus VGABIOS images - added support for the PCI data structure in biossums - updated year in copyright 2008-01-26 11:46 vruppert * BUGS (1.4), Makefile (1.20), README (1.14), TODO (1.13), vbe_display_api.txt (1.14): - whitespace cleanup 2006-11-26 10:43 vruppert * Makefile (1.19): - disable the generation of linemarkers by the preprocessor, since the latest versions of bcc don't like them 2006-09-02 13:15 vruppert * biossums.c (1.4): - the biossums utility no longer modifies VGABIOS images with proper checksum and size 2006-08-19 14:28 vruppert * Changelog (1.26), README (1.13), TODO (1.12): - updates for 0.6a release 2006-08-19 09:39 vruppert * vbe.c (1.58): - improved VGA compatible setup for VBE modes (disable CGA and Hercules compatible memory layout) 2006-08-18 20:39 vruppert * vbe.c (1.57): - improved VGA compatible setup for >=8bpp VBE modes (CRTC doubleword mode and GRDC shift register setting added) - now using symbolic name for CRTC address register 2006-08-15 20:42 vruppert * vbe.c (1.56), vbetables-gen.c (1.4): - init 4bpp VBE modes by a temporary switch to VGA mode 0x6A - all 4bpp VBE modes now enabled 2006-08-14 20:24 vruppert * vbe.c (1.55): - VGA compatible setup for VBE modes improved (Bochs hack can be removed now) 2006-08-12 07:51 vruppert * .cvsignore (1.1): - .cvsignore added for auto-generated file 2006-08-12 07:47 vruppert * vbe.c (1.54), vbe.h (1.27), vbe_display_api.txt (1.13), vbetables-gen.c (1.3): - cleaned up VBE memory size definitions (removed duplicate defines, main definition now in vbetables-gen.c) 2006-08-09 21:28 vruppert * vbetables.h (1.30): - removed auto-generated file 2006-08-09 21:26 vruppert * vbe.c (1.53), vbe.h (1.26), vbe_display_api.txt (1.12), vbetables-gen.c (1.2), vbetables.h (1.29): - VBE video memory increased to 8 MB - VBE dispi ID changed to B0C4 - documentation update 2006-07-11 08:03 vruppert * Makefile (1.18), vbetables-gen.c (1.1), vbetables.h (1.28): - generate vbetables.h dynamicly * initial patch from the qemu project by Fabrice Bellard * only add modes that fit in video memory (still 4 MB) * several other fixes (e.g. 4 bpp specific stuff, number of pages) 2006-07-10 07:47 vruppert * vgabios.c (1.66): - biosfn_scroll(): check variable 'i' for underflowing when scrolling downwards to avoid screen corruption 2006-07-10 07:47 vruppert * vbe.c (1.52): - VBE set bank functions failure handling added - VBE get/set logical scan line length fixes for the 4bpp mode 2006-07-08 13:27 vruppert * vbe.c (1.51), vbetables.h (1.27): - added special case for the 4 bpp when setting VBE display start - VBE mode table fixes 2006-07-07 13:30 vruppert * clext.c (1.12): - bank pointer must be set to 0 after a mode set 2006-06-21 16:58 vruppert * vbe.c (1.50), vbetables.h (1.26): - improved VBE display capabilities check (X resulution checked now) - removed obsolete defines (LFB always available, always generate dynamic list) - CR/LF to LF fixes 2006-06-18 15:22 vruppert * clext.c (1.11), vbe.c (1.49), vbe.h (1.25), vbetables.h (1.25), vgabios.c (1.65): - applied patch from the qemu project (Fabrice Bellard) * Cirrus SVGA now supports the "no clear" bit when switching to Cirrus or VESA mode * Bochs VBE protected mode interface improved * save/restore video state support for Bochs VBE and standard VGA added * Bochs VBE prepared for more modi 2006-03-25 10:19 vruppert * clext.c (1.10), vgabios.c (1.64), vgatables.h (1.10): - applied patch from Fabrice Bellard * added minimal support for the video parameter table (VPT) * added Cirrus SVGA mode 0x7b (1600x1200x8) 2005-12-26 19:50 vruppert * vbe.c (1.48), vgabios.c (1.63): - Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) 2005-12-26 19:50 vruppert * biossums.c (1.3): - biossums utility now supports VGABIOS sizes up to 64 kBytes 2005-09-21 18:45 vruppert * vgatables.h (1.9): - mode 0x11: all color planes must be enabled in this 2-color VGA mode 2005-08-30 18:41 vruppert * biossums.c (1.2): - missing license text added in biossums.c 2005-07-02 18:39 vruppert * vgabios.c (1.62): - BIOS configuration word usually reports initial mode 80x25 color text - vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the cursor row value 2005-05-24 16:50 vruppert * vbe.c (1.47), vgabios.c (1.61): - output to the vgabios info port can be disabled now. It is still enabled by default and always possible in debug mode. (based on a patch from Alex Beregszaszi) 2005-05-20 16:06 vruppert * vbe.c (1.46), vgabios.c (1.60): - fixed return value for the default case in the VBE section (non-debug mode) - removed unused macros HALT and PANIC_PORT 2005-03-07 20:39 vruppert * README (1.9): - updates for 0.5a release 2005-03-06 13:06 vruppert * Makefile (1.17): - vgabios files with cirrus support added to release target 2005-03-06 12:24 vruppert * Makefile (1.16): - cross compilation support added (patch from Alex Beregszaszi) 2005-03-05 13:03 vruppert * BUGS (1.3), README (1.8), TODO (1.11): - documentation updates 2004-12-04 15:26 vruppert * VGABIOS-lgpl-latest.bin (1.61), VGABIOS-lgpl-latest.cirrus.bin (1.13), VGABIOS-lgpl-latest.cirrus.debug.bin (1.13), VGABIOS-lgpl-latest.debug.bin (1.61), clext.c (1.9): - Cirrus extension: support for 1280x1024x15 and 1280x1024x16 modes added (patch from Fabrice Bellard) 2004-08-08 16:53 vruppert * VGABIOS-lgpl-latest.bin (1.60), VGABIOS-lgpl-latest.cirrus.bin (1.12), VGABIOS-lgpl-latest.cirrus.debug.bin (1.12), VGABIOS-lgpl-latest.debug.bin (1.60), clext.c (1.8): - use single bank mode for VBE - enable 16k granularity for VBE only 2004-07-30 19:33 vruppert * VGABIOS-lgpl-latest.bin (1.59), VGABIOS-lgpl-latest.cirrus.bin (1.11), VGABIOS-lgpl-latest.cirrus.debug.bin (1.11), VGABIOS-lgpl-latest.debug.bin (1.59), clext.c (1.7): - cirrus init: set standard vga mode and reset bitblt 2004-07-22 18:38 vruppert * VGABIOS-lgpl-latest.bin (1.58), VGABIOS-lgpl-latest.cirrus.bin (1.10), VGABIOS-lgpl-latest.cirrus.debug.bin (1.10), VGABIOS-lgpl-latest.debug.bin (1.58), clext.c (1.6), vbe.c (1.45), vbetables.h (1.24): - cirrus extension: tables for mode 1280x1024x8 added - vbe: dispi_set_xres() and dispi_set_virt_width() now modify vga compatible registers - vbe: mode list entry for mode 800x600x4 fixed 2004-07-18 20:23 vruppert * VGABIOS-lgpl-latest.bin (1.57), VGABIOS-lgpl-latest.cirrus.bin (1.9), VGABIOS-lgpl-latest.cirrus.debug.bin (1.9), VGABIOS-lgpl-latest.debug.bin (1.57), vgabios.c (1.59), vgatables.h (1.8): - disable CRTC write protection before setting new values - CRTC line for mode 0x6a fixed 2004-07-07 16:08 vruppert * Makefile (1.15), VGABIOS-lgpl-latest.bin (1.56), VGABIOS-lgpl-latest.cirrus.bin (1.8), VGABIOS-lgpl-latest.cirrus.debug.bin (1.8), VGABIOS-lgpl-latest.debug.bin (1.56), biossums.c (1.1), clext.c (1.5): - biossums utility for the Bochs BIOS adapted for the LGPL'd VGABIOS - VESA3 PMINFO checksum calculated in the source - 24 bpp mode entries fixed (patch from Fabrice Bellard) 2004-06-25 18:28 vruppert * VGABIOS-lgpl-latest.cirrus.bin (1.7), VGABIOS-lgpl-latest.cirrus.debug.bin (1.7), clext.c (1.4): - 4MB memory probe added (patch from Fabrice Bellard) 2004-06-25 17:31 vruppert * VGABIOS-lgpl-latest.bin (1.55), VGABIOS-lgpl-latest.cirrus.bin (1.6), VGABIOS-lgpl-latest.cirrus.debug.bin (1.6), VGABIOS-lgpl-latest.debug.bin (1.55), clext.c (1.3): - fixed value of sequencer reset register in cirrus mode table - fixed possible overflow error if cirrus start address is >256k 2004-06-23 21:11 vruppert * VGABIOS-lgpl-latest.bin (1.54), VGABIOS-lgpl-latest.cirrus.bin (1.5), VGABIOS-lgpl-latest.cirrus.debug.bin (1.5), VGABIOS-lgpl-latest.debug.bin (1.54), clext.c (1.2): - applied new patch for the cirrus extension from suzu * enable VESA LFB support if a Cirrus PCI adapter is detected * prepared VBE3 protected mode info block (test case required) - added VBE functions 4F06h and 4F07h - some bugfixes 2004-06-17 18:57 vruppert * Makefile (1.14), VGABIOS-lgpl-latest.bin (1.53), VGABIOS-lgpl-latest.cirrus.bin (1.2), VGABIOS-lgpl-latest.cirrus.debug.bin (1.2), VGABIOS-lgpl-latest.debug.bin (1.53): - fixed makefile targets for the binaries with cirrus extension 2004-06-16 21:11 vruppert * Makefile (1.13), VGABIOS-lgpl-latest.bin (1.52), VGABIOS-lgpl-latest.cirrus.bin (1.1), VGABIOS-lgpl-latest.cirrus.debug.bin (1.1), VGABIOS-lgpl-latest.debug.bin (1.52), clext.c (1.1), vgabios.c (1.58): - applied suzu's cirrus extension patch. Cirrus SVGA detection, most of the cirrus-specific modes and some basic VBE features are present now. 2004-05-31 21:15 vruppert * VGABIOS-lgpl-latest.bin (1.51), VGABIOS-lgpl-latest.debug.bin (1.51), vgabios.c (1.57): - write character in planar graphics modes: sequencer map mask must be 0x0f and bit operation must be 'replace' if bit 7 of attribute is clear - read/write pixel in planar graphics modes: bit mask setup simplified 2004-05-11 18:08 vruppert * VGABIOS-lgpl-latest.bin (1.50), VGABIOS-lgpl-latest.debug.bin (1.50), vgabios.c (1.56): - biosfn_select_vert_res rewritten in assembler - scroll text in planar graphics modes: attribute for blank line fixed - write character in planar graphics modes: graphics controller values fixed 2004-05-09 20:32 vruppert * VGABIOS-lgpl-latest.bin (1.49), VGABIOS-lgpl-latest.debug.bin (1.49), vbe.c (1.44), vbe.h (1.24), vgabios.c (1.55): - VBE init code and some dispi ioport functions rewritten in assembler - text scroll functions for CGA graphics modes added - scroll text in graphics modes: attribute for blank line fixed 2004-05-08 16:06 vruppert * BUGS (1.2), README (1.7), TODO (1.10), VGABIOS-lgpl-latest.bin (1.48), VGABIOS-lgpl-latest.debug.bin (1.48), vbe.c (1.43), vbe.h (1.23), vbe_display_api.txt (1.11), vgabios.c (1.54): - VBE internal functions dispi_set_enable and dispi_set_bank now called both from C and asm code - VBE function 0x03 rewritten in assembler - VBE function 0x08 cleaned up - text output and scroll functions for graphics modes rewritten using case structures - documentation and comments updated 2004-05-06 21:18 vruppert * VGABIOS-lgpl-latest.bin (1.47), VGABIOS-lgpl-latest.debug.bin (1.47), vbe.c (1.42), vbe.h (1.22), vgabios.c (1.53): - VBE functions 0x05, 0x06, 0x07 and some dispi ioport functions rewritten in assembler - VBE functions 0x06 and 0x07: get functions now supported, 15 bpp bug fixed 2004-05-05 19:24 vruppert * VGABIOS-lgpl-latest.bin (1.46), VGABIOS-lgpl-latest.debug.bin (1.46), vbe.c (1.41), vbe.h (1.21), vbe_display_api.txt (1.10), vgabios.c (1.52): - 8 bit DAC capability flag set - vbe_biosfn_set_get_dac_palette_format implemented - VBE api description updated - C definitions from header files now used assembler code 2004-05-02 17:27 vruppert * VGABIOS-lgpl-latest.bin (1.45), VGABIOS-lgpl-latest.debug.bin (1.45), vgabios.c (1.51): - text scroll functions for PLANAR1/PLANAR4 graphics modes added - function biosfn_get_ega_info rewritten in assembler - read/write graphics pixel functions rewritten using a case structure 2004-05-01 16:03 vruppert * VGABIOS-lgpl-latest.bin (1.44), VGABIOS-lgpl-latest.debug.bin (1.44), vgabios.c (1.50): - biosfn_enable_cursor_emulation rewritten in assembler - remap of the cursor shape depends on modeset control bit 0 - text output in PLANAR4 modes now supports attribute bit 7 (XOR with background) 2004-04-25 20:13 vruppert * VGABIOS-lgpl-latest.bin (1.43), VGABIOS-lgpl-latest.debug.bin (1.43), vgabios.c (1.49), vgatables.h (1.7): - table entries for vga mode 0x0f fixed (PLANAR2 exists on EGA only) - function release_font_access now supports the monochrome text mode - PLANAR1 modes now supported in text output functions and read/write pixel - function AH=0x12/BL=0x32 rewritten in assembler 2004-04-25 08:45 vruppert * VGABIOS-lgpl-latest.bin (1.42), VGABIOS-lgpl-latest.debug.bin (1.42), vgabios.c (1.48): - block address calculation in font functions fixed - functions AX=0x1103, AH=0x12/BL=0x31 and AH=0x12/BL=0x33 rewritten in assembler 2004-04-24 09:59 vruppert * VGABIOS-lgpl-latest.bin (1.41), VGABIOS-lgpl-latest.debug.bin (1.41), vgabios.c (1.47): - read/write graphics pixel for PLANAR4 modes added - CGA specific functions (group AH = 0x0B) implemented 2004-04-23 14:34 vruppert * VGABIOS-lgpl-latest.bin (1.40), VGABIOS-lgpl-latest.debug.bin (1.40), vgabios.c (1.46): - remaining palette and dac read/write functions (except gray scale summing) rewritten in assembler 2004-04-18 13:43 vruppert * VGABIOS-lgpl-latest.bin (1.39), VGABIOS-lgpl-latest.debug.bin (1.39), vgabios.c (1.45): - some palette and dac read/write functions rewritten in assembler - main int10 debug message now works with assembler functions, too 2004-04-18 09:15 japj * vbe.c (1.40): updated my email address + put vgabios url in the bios copyright string (instead of my old email address) 2004-04-17 07:18 vruppert * VGABIOS-lgpl-latest.bin (1.38), VGABIOS-lgpl-latest.debug.bin (1.38), vgabios.c (1.44): - biosfn_set_video_mode: don't load DAC registers if default palette loading is disabled. Perform gray scale summing if enabled. - biosfn_perform_gray_scale_summing: switch between DAC read and write mode is required to make this function work. Maximum DAC value always set to 0x3f. 2004-04-08 17:50 vruppert * VGABIOS-lgpl-latest.bin (1.37), VGABIOS-lgpl-latest.debug.bin (1.37), vgabios.c (1.43): - write character function for the LINEAR8 mode - get_font_access() and release_font_access() rewritten in assembler - fixed wrong variable name in the init code 2004-04-06 19:31 vruppert * VGABIOS-lgpl-latest.bin (1.36), VGABIOS-lgpl-latest.debug.bin (1.36), vgabios.c (1.42): - init functions rewitten in assembler - function biosfn_set_display_code rewritten in assembler 2004-04-05 19:40 vruppert * VGABIOS-lgpl-latest.bin (1.35), VGABIOS-lgpl-latest.debug.bin (1.35), vgabios.c (1.41): - functions biosfn_get_video_mode() and biosfn_read_display_code() rewritten in assembler 2004-04-04 18:20 vruppert * VGABIOS-lgpl-latest.bin (1.34), VGABIOS-lgpl-latest.debug.bin (1.34), vgabios.c (1.40): - write character function for CGA modes added - read/write graphics pixel for CGA and LINEAR8 modes added 2004-02-23 21:08 vruppert * VGABIOS-lgpl-latest.bin (1.33), VGABIOS-lgpl-latest.debug.bin (1.33), vbe.c (1.39): - dispi_get_max_bpp(): restore the original value of the vbe enable register 2004-02-22 14:17 vruppert * README (1.6), vbe.c (1.38), vbe.h (1.20), vbe_display_api.txt (1.9), VGABIOS-lgpl-latest.bin (1.32), VGABIOS-lgpl-latest.debug.bin (1.32): - new function dispi_get_max_bpp() returns the bpp capabilities of the Bochs gui - create the mode list depending on the supported bpp capability - unused stuff removed - documentation updated 2004-02-21 18:20 vruppert * vbe.c (1.37), vbe.h (1.19), vbetables.h (1.23), VGABIOS-lgpl-latest.bin (1.31), VGABIOS-lgpl-latest.debug.bin (1.31): - dynamicly genarated vbe mode_info list works now 2003-11-17 21:04 vruppert * vbe.c (1.36), vbetables.h (1.22), vgabios.c (1.39), vgatables.h (1.6), VGABIOS-lgpl-latest.bin (1.30), VGABIOS-lgpl-latest.debug.bin (1.30): - new VBE presence flag stored at unused BDA address 0xB9 - VBE init code rewritten - added BIOS TTY flag for VBE mode 0x0102 (TODO: scrolling) - vgabios_init_func: load and activate text font already done by set_video_mode - function biosfn_get_all_palette_reg() fixed 2003-11-06 00:26 cbothamy * README (1.5): - add changes for 0.4c release 2003-11-06 00:22 cbothamy * VGABIOS-lgpl-latest.bin (1.29), VGABIOS-lgpl-latest.debug.bin (1.29): - compile vgabios.c rev1.38 2003-11-06 00:21 cbothamy * vgabios.c (1.38): - activate char table after loading it when setting a text video mode 2003-11-06 00:19 cbothamy * Makefile (1.12): - when making a release, remove unwanted files first, and exclude CVS from the tarball 2003-11-04 22:50 cbothamy * ChangeLog (1.20, v0_4b): - update ChangeLog for 0.4b release 2003-11-04 22:49 cbothamy * README (1.4, v0_4b): - update Changes for 0.4b release 2003-11-04 20:26 vruppert * vgabios.c (1.37), VGABIOS-lgpl-latest.bin (1.28), VGABIOS-lgpl-latest.debug.bin (1.28) (utags: v0_4b): - biosfn_get_font_info(): character height must be returned in CX 2003-11-03 21:57 vruppert * vbe.c (1.35, v0_4b), vgabios.c (1.36), VGABIOS-lgpl-latest.bin (1.27), VGABIOS-lgpl-latest.debug.bin (1.27): - the 'noclearmem' flag is not stored in the 'current video mode' register (0040h:0049h) - VBE also stores the 'noclear' flag in the 'video control' register (0040h:0087h) 2003-10-05 10:06 vruppert * vbe.h (1.18, v0_4b), vbe_display_api.txt (1.8, v0_4b), VGABIOS-lgpl-latest.bin (1.26), VGABIOS-lgpl-latest.debug.bin (1.26): - changed VBE i/o registers to 0x01CE/CF (suggestion from Daniel Gimpelevich) 2003-08-18 18:38 vruppert * VGABIOS-lgpl-latest.bin (1.25), VGABIOS-lgpl-latest.debug.bin (1.25), vgabios.c (1.35): - wrong offsets to the character tables (INT 0x1F/0x43) fixed (underscore added) - functions accessing the CRT controller optimized using a local variable 'crtc_addr' 2003-08-17 15:46 cbothamy * ChangeLog (1.19, v0_4a): - ChangeLog is now automatically generated by running "cvs2cl -r -t -P -S" - update ChangeLog for 0.4a release 2003-08-17 15:44 cbothamy * README (1.3, v0_4a): - added the old ChangeLog in the HOSTORY section of the README file - update History for 0.4a release, with a summary of Changes 2003-08-17 15:24 cbothamy * Makefile (1.11, v0_4b, v0_4a): - fix Makefile for "release" target 2003-08-16 01:49 cbothamy * Makefile (1.10), README (1.2), VGABIOS-lgpl-latest.bin (1.24, v0_4a), VGABIOS-lgpl-latest.debug.bin (1.24, v0_4a), vgabios.c (1.34, v0_4a): - update the Makefile for releases - remove references to old plex86 website - update the Makefile so it build VGABIOS-lgpl-latest.bin and VGABIOS-lgpl-latest.debug.bin 2003-08-07 18:17 vruppert * VGABIOS-lgpl-latest.bin (1.23), VGABIOS-lgpl-latest.debug.bin (1.23): - current VBE mode now stored in BDA (unused address 0xBA) 2003-08-07 17:54 vruppert * vbe.c (1.34), vgatables.h (1.5, v0_4b) (utags: v0_4a): - current VBE mode now stored in BDA (unused address 0xBA) 2003-07-20 18:05 vruppert * vgabios.c (1.33), VGABIOS-lgpl-latest.bin (1.22), VGABIOS-lgpl-latest.debug.bin (1.22): - fixed a few functions accessing the attribute controller 2003-07-19 09:33 vruppert * vgabios.c (1.32), VGABIOS-lgpl-latest.bin (1.21), VGABIOS-lgpl-latest.debug.bin (1.21): - re-enable video after programming the attribute controller - biosfn_set_all_palette_reg(): number of palette registers fixed 2003-07-16 22:32 vruppert * ChangeLog (1.18), vbe.c (1.33), vbe.h (1.17, v0_4a), vbe_display_api.txt (1.7, v0_4a), vgabios.c (1.31), VGABIOS-lgpl-latest.bin (1.20), VGABIOS-lgpl-latest.debug.bin (1.20): - LFB flag now stored in the register VBE_DISPI_INDEX_ENABLE - release date in Changelog fixed - release date of VBE BIOS 0.6 was the same as VGA BIOS 0.3b - year changed in copyright messages 2003-07-15 12:40 vruppert * VGABIOS-lgpl-latest.bin (1.19), VGABIOS-lgpl-latest.debug.bin (1.19): - new function dispi_get_bpp() - function vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - number of image pages of all VBE modes fixed 2003-07-15 12:35 vruppert * vbe.c (1.32), vbetables.h (1.21, v0_4b, v0_4a): - new function dispi_get_bpp() - function vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - number of image pages of all VBE modes fixed 2003-07-14 19:45 vruppert * vbe_display_api.txt (1.6): - description of VBE_DISPI_ interface 0xb0c2 added 2003-07-10 19:07 vruppert * vbe.c (1.31), vbetables.h (1.20), VGABIOS-lgpl-latest.bin (1.18), VGABIOS-lgpl-latest.debug.bin (1.18): - 15 bpp VBE modes added - "Bochs own" mode 0x142 (640x480x32bpp) added 2003-07-01 19:00 vruppert * vbe.c (1.30), vbe.h (1.16), vbetables.h (1.19), VGABIOS-lgpl-latest.bin (1.17), VGABIOS-lgpl-latest.debug.bin (1.17): - VBE preserve display memory feature implemented - VBE mode entries 0x117 and 0x118 added 2003-06-30 21:27 vruppert * vbe.c (1.29), vbe.h (1.15), vbetables.h (1.18), VGABIOS-lgpl-latest.bin (1.16), VGABIOS-lgpl-latest.debug.bin (1.16): - VBE mode info blocks of modes with >8bpp enabled - VBE modes with 24 bpp: bytes per scanline fixed - vbe_biosfn_set_mode() now supports >8bpp - VBE will be enabled with new VBE_DISPI_ID2 (0xB0C2) 2003-06-29 12:53 vruppert * vbetables.h (1.17), VGABIOS-lgpl-latest.bin (1.15), VGABIOS-lgpl-latest.debug.bin (1.15): - duplicate lines with VBE_MODE_ATTRIBUTE_GRAPHICS_MODE removed - VBE mode info items of currently unsupported modes fixed 2003-06-15 21:19 vruppert * vgabios.c (1.30), VGABIOS-lgpl-latest.bin (1.14), VGABIOS-lgpl-latest.debug.bin (1.14): - function write_gfx_char() rewritten 2003-04-26 09:27 vruppert * VGABIOS-lgpl-latest.debug.bin (1.13): - added missing VBE function dispi_get_bank() - added missing return codes for VBE function 4F05h - memory size is always reported in VBE function 4F00h - fixed scan line length for VBE mode 0102h - fixed function set_active_page() for graphics modes - fixed the page sizes of some VGA modes 2003-04-26 09:22 vruppert * vbe.c (1.28), vbetables.h (1.16), vgabios.c (1.29), vgatables.h (1.4), VGABIOS-lgpl-latest.bin (1.13): - added missing VBE function dispi_get_bank() - added missing return codes for VBE function 4F05h - memory size is always reported in VBE function 4F00h - fixed scan line length for VBE mode 0102h - fixed function set_active_page() for graphics modes - fixed the page sizes of some VGA modes 2003-04-20 09:51 vruppert * vgabios.c (1.28), vgatables.h (1.3), VGABIOS-lgpl-latest.bin (1.12), VGABIOS-lgpl-latest.debug.bin (1.12): - function write_gfx_char() now supports different font sizes - some entries of the static functionality table fixed 2003-04-18 09:23 vruppert * vbe.c (1.27), vbe.h (1.14), vbetables.h (1.15): - applied patch #1331 * new function dispi_set_bank_farcall() * VBE mode info item WinFuncPtr points to the new function if the flag VBE_WINDOW_ATTRIBUTE_RELOCATABLE is set * flag VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE added 2003-02-11 20:17 vruppert * VGABIOS-lgpl-latest.bin (1.11), VGABIOS-lgpl-latest.debug.bin (1.11), vbe.c (1.26), vbetables.h (1.14): - VBE mode search rewritten * improved function mode_info_find_mode() is now used by the VBE functions 0x4F01 and 0x4F02 * removed all mode list entries with the LFB bit set. LFB detection is now present in the function mode_info_find_mode() 2003-02-09 20:59 vruppert * VGABIOS-lgpl-latest.bin (1.10), VGABIOS-lgpl-latest.debug.bin (1.10), vgabios.c (1.27): - function write_gfx_char(): memory address now calculated in this function; background color is always black - function biosfn_write_char_attr(): the count parameter is now used in graphics modes too - function biosfn_write_char_only() works the same way as function biosfn_write_char_attr() in graphics mode - copying charmap data optimized using memcpyb() 2003-02-09 11:36 vruppert * VGABIOS-lgpl-latest.bin (1.9), VGABIOS-lgpl-latest.debug.bin (1.9): - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA modes with the LFB flag set removed from the list (Linux doesn't like mode numbers > 0x07ff) 2003-02-09 11:02 vruppert * vbe.c (1.25), vbe.h (1.13), vbetables.h (1.13): - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA modes with the LFB flag set removed from the list (Linux doesn't like mode numbers > 0x07ff) 2003-02-08 13:04 vruppert * vbe.c (1.24), vgabios.c (1.26): - vbe_biosfn_return_current_mode() now returns the active standard VGA mode TODO: return VESA mode if enabled - biosfn_set_video_mode() now clears the screen in CGA mode correctly - write character functions are now working in all PLANAR4 graphics modes - added stubs for unimplemented features in graphics modes 2003-02-04 22:19 vruppert * VGABIOS-lgpl-latest.bin (1.8), VGABIOS-lgpl-latest.debug.bin (1.8): - set video mode: clear vga memory in graphics mode - set video mode: load default font in text mode - write character implemented for graphics mode 0x12 2003-02-04 22:06 vruppert * vgabios.c (1.25): - set video mode: clear vga memory in graphics mode - set video mode: load default font in text mode - write character implemented for graphics mode 0x12 2003-01-21 19:30 vruppert * vgabios.c (1.24): - remap the cursor size if the char height is > 8 and the new values are < 8 2003-01-20 18:24 cbothamy * Makefile (1.9): - fix so make -j2 does not overwrite temp files 2003-01-19 12:35 vruppert * vgabios.c (1.23): - function set_scan_lines() recalculates the number of rows and the page size - new values for char height, text rows and page size are stored in the BIOS data segment - asm helper function idiv_u added 2003-01-15 18:49 cbothamy * VGABIOS-lgpl-latest.bin (1.7), VGABIOS-lgpl-latest.debug.bin (1.7): - compile vgabios rev 1.22 2003-01-15 18:49 cbothamy * vgabios.c (1.22): - fix bug found by ams : a 8bits index value was compared to 0x100 in some cases in biosfn_set_all_dac_reg, biosfn_read_all_dac_reg, biosfn_perform_gray_scale_summing 2003-01-15 17:34 cbothamy * Makefile (1.8): - fix symbol table file names, discovered by ams 2003-01-04 21:20 vruppert * VGABIOS-lgpl-latest.bin (1.6), VGABIOS-lgpl-latest.debug.bin (1.6), vgabios.c (1.21): - biosfn_set_video_mode(): reset attribute controller flip-flop before setting up the controller's registers (bug found with amidiag) 2003-01-04 09:50 vruppert * vbe.c (1.23): - VBE function 0x00 returns VBE 1.x compatible information if no VBE signature is present 2003-01-01 12:44 vruppert * VGABIOS-lgpl-latest.bin (1.5), VGABIOS-lgpl-latest.debug.bin (1.5): - SVGA mode 0x6A (800x600x4) added to the list of graphics modes 2002-12-31 18:07 vruppert * vgatables.h (1.2): - SVGA mode 0x6A (800x600x4) added to the list of graphics modes 2002-11-23 10:38 cbothamy * ChangeLog (1.17, v0_3b): - fix changelog for 0.3b release 2002-10-20 17:12 vruppert * VGABIOS-lgpl-latest.bin (1.4), VGABIOS-lgpl-latest.debug.bin (1.4), vgabios.c (1.20) (utags: v0_3b): - new function set_scan_lines() for the font size change (patch from Hartmut Birr) - cursor shape start and end must be updated in set_scan_lines() - set_scan_lines() is called by the functions 0x1110, 0x1111, 0x1112 and 0x1114 after copying the font data 2002-10-04 08:20 vruppert * VGABIOS-lgpl-latest.bin (1.3), VGABIOS-lgpl-latest.debug.bin (1.3), vgabios.c (1.19): - biosfn_set_single_dac_reg(): the red value is stored in DH 2002-09-19 19:05 cbothamy * VGABIOS-lgpl-latest.bin (1.2), VGABIOS-lgpl-latest.debug.bin (1.2): - updated with latest changes 2002-09-19 19:03 cbothamy * ChangeLog (1.16), Makefile (1.7, v0_3b), vbe.c (1.22, v0_3b), vgabios.c (1.18), vgabios.h (1.3, v0_4b, v0_4a, v0_3b): - updated the Makefile - removed display of copyrights. - changed the Copyright string to "LGPL VGABios developers" 2002-09-08 21:14 vruppert * vgabios.c (1.17): - set the cursor shape depending on the current font height - clear BL before calling int 0x10 function 0x1103 in vgabios_init_func 2002-08-23 22:58 cbothamy * vbe.c (1.21), vbetables.h (1.12, v0_3b): - added lfb-mode numbers (patch from mathis) 2002-07-21 21:57 japj * vbe.c (1.20), vgabios.c (1.16): gcc2/3 preprocessing fix 2002-05-18 16:55 cbothamy * vgabios.c (1.15): - include patch from Volker that adds some text font functions 2002-05-01 23:13 japj * VGABIOS-lgpl-latest.bin (1.1), VGABIOS-lgpl-latest.debug.bin (1.1): adding latest bin & debug bin of the vgabios 2002-04-29 14:50 japj * ChangeLog (1.15), vbe.c (1.19), vbe.h (1.12, v0_3b), vbetables.h (1.11), vgabios.c (1.14): - applying hw scrolling/multibuffering patch 2002-04-25 21:59 japj * Makefile (1.6), vbe.c (1.18), vgabios.c (1.13): - reverting #asm/##asm & endasm patch (does not work with with cygwin) 2002-04-19 19:38 japj * Makefile (1.5), vbe.c (1.17), vgabios.c (1.12): - fixing preprocessing of vgabios with latest gcc (from Mandrake 8.2) 2002-04-08 23:44 japj * ChangeLog (1.14), vbe_display_api.txt (1.5, v0_3b): - preparing docs for new DISPI interface (for hardware scrolling) 2002-04-03 19:06 japj * ChangeLog (1.13), TODO (1.9, v0_4b, v0_4a, v0_3b), vbe.c (1.16): - defaulting LFB on + updated changelog & todo 2002-04-03 00:38 cbothamy * vbe.c (1.15), vgabios.c (1.11): - changed the logging ports to 0x500 -> 0x502 2002-03-14 17:54 japj * vbe.c (1.14): - vbetables.h is dependant upon some defines (VBE_HAVE_LFB), so put the include *after* the define 2002-03-13 21:47 japj * ChangeLog (1.12), TODO (1.8), vbe.c (1.13), vbetables.h (1.10), vgabios.c (1.10): - made LFB dependant upon define - not implement vbe functions return failure - updated todo & docs for things after bochs 1.4 2002-03-13 19:46 japj * vbe.h (1.11), vbe_display_api.txt (1.4): - added max video memory + documented what is in the 0xb0c0 interface 2002-03-12 02:33 cbothamy * ChangeLog (1.11), Makefile (1.4): - updated for 0.3a. Merged vgabios.bin and vbebios.bin 2002-03-10 21:36 japj * ChangeLog (1.10), vbetables.h (1.9): - added LFB modes for testing with vbe-lfb patch in Bochs 2002-03-10 17:42 japj * vbe.c (1.12, v0_3a): - show people when they do NOT have VBE support available 2002-03-10 17:36 japj * TODO (1.7, v0_3a), vbe.c (1.11), vbe.h (1.10, v0_3a), vgabios.c (1.9, v0_3a): - cleanup of vbe internal functions (set 8bpp mode is now dependant on ModeInfo content instead of hardcoded functions) 2002-03-10 17:20 cbothamy * ChangeLog (1.9, v0_3a), TODO (1.6): - updated for 0.3a 2002-03-10 17:19 cbothamy * vbe.c (1.10), vbe.h (1.9): - added vbe_has_vbe_display function that detects an attached vbe display 2002-03-10 17:12 cbothamy * vgabios.c (1.8): - vbe calls are done only if a vbe display is detected 2002-03-10 11:25 japj * vbe.h (1.8), vbe_display_api.txt (1.3, v0_3a): - preparing for LFB support 2002-03-09 14:25 japj * vgabios.c (1.7): - fixing initial cursor shape to _ instead of - 2002-03-08 23:08 japj * ChangeLog (1.8), TODO (1.5), vbe.c (1.9), vbe.h (1.7), vgabios.c (1.6): - updating vbe code to new API 2002-03-08 21:48 japj * vbe.c (1.8), vbe.h (1.6), vbetables.h (1.8, v0_3a): - updating vbe code with #defines from API 2002-03-08 21:31 japj * vbe_display_api.txt (1.2): - adding some text about how banks work 2002-03-08 21:09 japj * ChangeLog (1.7), vbe_display_api.txt (1.1): - adding vbe_display_api documentation 2002-03-07 21:36 japj * ChangeLog (1.6), vbe.c (1.7), vbetables.h (1.7): - added 1024x768xbpp support - some more cleanups/comments 2002-03-06 21:55 japj * ChangeLog (1.5), TODO (1.4), vbe.c (1.6), vbetables.h (1.6), vgabios.c (1.5): - updated changelog with new modi - added 640x480x8 (Mandrake Installer can use this!) - added pre VBE2 compatible 'detection' - fixed problem when normal vga set mode wouldn't disable vbe mode 2002-03-06 20:59 japj * TODO (1.3), vbe.c (1.5), vbe.h (1.5), vbetables.h (1.5), vgabios.c (1.4): - adding 640x400x8 and 800x600x8 vbe support (this depends HEAVILY on my bochs vga code patch - japj) 2002-03-06 18:00 japj * vbe.c (1.4), vbe.h (1.4), vbetables.h (1.4): - implemented banked & lfb support for 320x200x8bpp (some fixes for vbetest program not displaying anything) 2002-03-05 20:25 japj * Makefile (1.3, v0_3a): for vbe debug bios: - print debugging information in assembly output - print source code in assembly output 2002-03-01 19:39 japj * ChangeLog (1.4), TODO (1.2), vbe.c (1.3), vbe.h (1.3), vbetables.h (1.3): - added vbe support for 320x200x8 using the standard vgamode (0x13) 2002-02-19 00:29 japj * ChangeLog (1.3): - updating ChangeLog with lfbprof 2002-02-18 23:26 japj * tests/lfbprof/: lfbprof.c (1.2), lfbprof.h (1.2) (utags: v0_3a, v0_3b, v0_4a, v0_4b): - fixed unsigned short for mode list (-1 != 0xffff otherwise) - fixed LfbMapRealPointer macro mask problem (some modes were skipped) - added some extra 'debugging' printf's 2002-02-18 23:07 japj * tests/lfbprof/: Makefile (1.1, v0_4b, v0_4a, v0_3b, v0_3a), lfbprof.c (1.1), lfbprof.h (1.1): - Adding lfbprof testprogram (for vbe testing purposes) It needs to be compiled with the Watcom C Compiler 2002-02-18 18:48 japj * vbe.c (1.2), vbe.h (1.2): - cosmetic updates to vbe.c/h + added bunch of FIXMEs for work that needs to be done 2002-02-18 18:34 japj * vbetables.h (1.2): - cosmetic updates in vbetables.h 2002-02-18 18:32 japj * ChangeLog (1.2): updated changelog with merge of vbebios 0.2 2002-02-18 18:07 japj * vgabios.c (1.3): - small cosmetic cleanup in vgabios vbe code + added FIXMEs 2002-02-18 17:55 japj * Makefile (1.2), dataseghack (1.2, v0_4b, v0_4a, v0_3b, v0_3a), vbe.c (1.1), vbe.h (1.1), vbetables.h (1.1), vgabios.c (1.2), vgabios.h (1.2, v0_3a): - merging with vbebios 0.2 release 2002-02-18 11:31 cbothamy * BUGS (1.1, v0_4b, v0_4a, v0_3b, v0_3a), COPYING (1.1, v0_4b, v0_4a, v0_3b, v0_3a), ChangeLog (1.1), Makefile (1.1), Notes (1.1, v0_4b, v0_4a, v0_3b, v0_3a), README (1.1, v0_3b, v0_3a), TODO (1.1), dataseghack (1.1), vgabios.c (1.1), vgabios.h (1.1), vgafonts.h (1.1, v0_4b, v0_4a, v0_3b, v0_3a), vgatables.h (1.1, v0_3b, v0_3a), tests/testbios.c (1.1, v0_4b, v0_4a, v0_3b, v0_3a): - initial import vgabios-0.7a/TODO0000644000175000017500000000101511653243015013516 0ustar guillemguillemShort term : ------------ General - Fix init mode (ah=00). Should use more BIOS variables - Add new functionalities and modify static functionality table - Performance : 16 bits IO v0.8 - Implement the remaining functions (don't know if all are needed): - display switch interface ah=12 bl=35 - video refresh control ah=12 bl=36 v1.0 - Bugfixes ================================================================================================= VBE: ---- Long term: - have text io functions in vbe mode vgabios-0.7a/tests/0000755000175000017500000000000007556274206014210 5ustar guillemguillemvgabios-0.7a/tests/testbios.c0000644000175000017500000001671707434154025016213 0ustar guillemguillem/* This is a little turbo C program that executes several int10, and let you inspect the content of the vgabios area It is used to test the behavior of the vgabios */ #include #include #include typedef unsigned char Bit8u; typedef unsigned short Bit16u; typedef struct {Bit8u initial; Bit8u current; Bit16u nbcols; Bit16u regen; Bit16u start; Bit16u curpos[8]; Bit8u curtyp; Bit8u curpage; Bit16u crtc; Bit16u msr; Bit16u cgapal; Bit8u nbrows; Bit16u cheight; Bit8u ctl; Bit8u switches; Bit8u modeset; Bit8u dcc; Bit16u vsseg; Bit16u vsoffset; } BIOSAREA; void int10ax0003(struct REGPACK *regs) { regs->r_ax=0x0003; intr(0x10,regs); } void int10ax02(struct REGPACK *regs) { regs->r_ax=0x0200; regs->r_bx=0x0000; regs->r_dx=0x1710; intr(0x10,regs); printf("We are now at 24/17"); } void int10ax03(struct REGPACK *regs) { regs->r_ax=0x0300; regs->r_bx=0x0000; intr(0x10,regs); printf("\nCursor is ax%04x cx%04x dx%04x\n",regs->r_ax,regs->r_cx,regs->r_dx); } void int10ax0501(struct REGPACK *regs) { regs->r_ax=0x0501; intr(0x10,regs); regs->r_ax=0x0e61; regs->r_bx=0x0000; intr(0x10,regs); printf("We are now on page 2"); } void int10ax0602(struct REGPACK *regs) { regs->r_ax=0x0602; regs->r_bx=0x0700; regs->r_cx=0x0101; regs->r_dx=0x0a0a; intr(0x10,regs); printf("Scrolled 2 up"); } void int10ax0702(struct REGPACK *regs) { regs->r_ax=0x0702; regs->r_bx=0x0700; regs->r_cx=0x0101; regs->r_dx=0x0a0a; intr(0x10,regs); printf("Scrolled 2 down"); } void int10ax08(struct REGPACK *regs) { regs->r_ax=0x0800; regs->r_bx=0x0000; intr(0x10,regs); } void int10ax09(struct REGPACK *regs) { char attr; regs->r_ax=0x0501; intr(0x10,regs); for(attr=0;attr<16;attr++) {printf("%02x ",attr); regs->r_ax=0x0961+attr; regs->r_bx=0x0100+attr; regs->r_cx=0x0016; intr(0x10,regs); printf("\n"); } } void int10ax0a(struct REGPACK *regs) { regs->r_ax=0x0501; intr(0x10,regs); regs->r_ax=0x0a62; regs->r_bx=0x0101; regs->r_cx=0x0016; intr(0x10,regs); } void int10ax0f(struct REGPACK *regs) { regs->r_ax=0x0501; intr(0x10,regs); regs->r_ax=0x0f00; intr(0x10,regs); } void int10ax1b(struct REGPACK *regs) {unsigned char table[64]; unsigned char far *ptable; int i; regs->r_ax=0x0501; intr(0x10,regs); regs->r_ax=0x1b00; regs->r_bx=0x0000; ptable=&table; regs->r_es=FP_SEG(ptable); regs->r_di=FP_OFF(ptable); printf("Read state info in %04x:%04x\n",regs->r_es,regs->r_di); intr(0x10,regs); for(i=0;i<64;i++) {if(i%16==0)printf("\n%02x ",i); printf("%02x ",table[i]); } printf("\n"); } static unsigned char var[64]; void int10ax13(struct REGPACK *regs) {unsigned char far *pvar; pvar=&var; regs->r_ax=0x1300; regs->r_bx=0x000b; regs->r_dx=0x1010; regs->r_cx=0x0002; regs->r_es=FP_SEG(pvar); regs->r_bp=FP_OFF(pvar); pokeb(regs->r_es,regs->r_bp,'t'); pokeb(regs->r_es,regs->r_bp+1,'b'); printf("Writing from %04x:%04x\n",regs->r_es,regs->r_bp); intr(0x10,regs); } void switch_50(struct REGPACK *regs) { regs->r_ax=0x1202; regs->r_bx=0x3000; intr(0x10,regs); regs->r_ax=0x0003; intr(0x10,regs); regs->r_ax=0x1112; regs->r_bx=0x0000; intr(0x10,regs); } char exec_function(struct REGPACK *regs) {char c; printf("--- Functions --------------------\n"); printf("a. int10 ax0003\t"); printf("b. int10 ax02\t"); printf("c. int10 ax03\t"); printf("d. int10 ax0501\n"); printf("e. int10 ax0602\t"); printf("f. int10 ax0702\t"); printf("g. int10 ax08\t"); printf("h. int10 ax09\t"); printf("i. int10 ax0a\n"); printf("j. int10 ax0f\t"); printf("k. int10 ax1b\t"); printf("l. int10 ax13\n"); printf("q. Quit\t"); printf("r. switch to 50 lines\n"); c=getche(); switch(c) {case 'a': int10ax0003(regs); break; case 'b': int10ax02(regs); break; case 'c': int10ax03(regs); break; case 'd': int10ax0501(regs); break; case 'e': int10ax0602(regs); break; case 'f': int10ax0702(regs); break; case 'g': int10ax08(regs); break; case 'h': int10ax09(regs); break; case 'i': int10ax0a(regs); break; case 'j': int10ax0f(regs); break; case 'k': int10ax1b(regs); break; case 'l': int10ax13(regs); break; case 'q': break; case 'r': switch_50(regs); break; default: printf("No such function!\n"); } if(c=='q')return 1; while(kbhit()==0); c=getch(); return 0; } void read_bios_area(BIOSAREA *biosarea) { biosarea->initial=peekb(0x40,0x10); biosarea->current=peekb(0x40,0x49); biosarea->nbcols=peek(0x40,0x4a); biosarea->regen=peek(0x40,0x4c); biosarea->start=peek(0x40,0x4e); biosarea->curpos[0]=peek(0x40,0x50); biosarea->curpos[1]=peek(0x40,0x52); biosarea->curpos[2]=peek(0x40,0x54); biosarea->curpos[3]=peek(0x40,0x56); biosarea->curpos[4]=peek(0x40,0x58); biosarea->curpos[5]=peek(0x40,0x5a); biosarea->curpos[6]=peek(0x40,0x5c); biosarea->curpos[7]=peek(0x40,0x5e); biosarea->curtyp=peek(0x40,0x60); biosarea->curpage=peekb(0x40,0x62); biosarea->crtc=peek(0x40,0x63); biosarea->msr=peekb(0x40,0x65); biosarea->cgapal=peekb(0x40,0x66); biosarea->nbrows=peekb(0x40,0x84); biosarea->cheight=peek(0x40,0x85); biosarea->ctl=peekb(0x40,0x87); biosarea->switches=peekb(0x40,0x88); biosarea->modeset=peekb(0x40,0x89); biosarea->dcc=peekb(0x40,0x8a); biosarea->vsseg=peek(0x40,0xa8); biosarea->vsoffset=peek(0x40,0xaa); } void show_bios_area(BIOSAREA *biosarea) { printf("--- BIOS area --------------------\n"); printf("initial : %02x\t",biosarea->initial); printf("current : %02x\t",biosarea->current); printf("nbcols : %04x\t",biosarea->nbcols); printf("regen : %04x\t",biosarea->regen); printf("start : %04x\n",biosarea->start); printf("curpos : %04x %04x %04x %04x %04x %04x %04x %04x\n", biosarea->curpos[0], biosarea->curpos[1], biosarea->curpos[2], biosarea->curpos[3], biosarea->curpos[4], biosarea->curpos[5], biosarea->curpos[6], biosarea->curpos[7]); printf("curtyp : %04x\t",biosarea->curtyp); printf("curpage : %02x\t",biosarea->curpage); printf("crtc : %04x\t",biosarea->crtc); printf("msr : %04x\n",biosarea->msr); printf("cgapal : %04x\t",biosarea->cgapal); printf("nbrows-1: %02x\t",biosarea->nbrows); printf("cheight : %04x\t",biosarea->cheight); printf("ctl : %02x\n",biosarea->ctl); printf("switches: %02x\t",biosarea->switches); printf("modeset : %02x\t",biosarea->modeset); printf("dcc : %02x\t",biosarea->dcc); printf("vs : %04x:%04x\n",biosarea->vsseg,biosarea->vsoffset); } void show_regs(struct REGPACK *regs) { printf("--- Registers --------------------\n"); printf("ax %04x\t",regs->r_ax); printf("bx %04x\t",regs->r_bx); printf("cx %04x\t",regs->r_cx); printf("dx %04x\t",regs->r_dx); printf("ds %04x\t",regs->r_ds); printf("si %04x\t",regs->r_si); printf("es %04x\t",regs->r_es); printf("di %04x\n",regs->r_di); } void reset_videomode() { struct REGPACK regs; regs.r_ax=0x0003; intr(0x10,®s); } void main() { BIOSAREA biosarea; struct REGPACK regs; directvideo=0; while(1) { read_bios_area(&biosarea); reset_videomode(); show_bios_area(&biosarea); show_regs(®s); if(exec_function(®s)!=0)break; } } vgabios-0.7a/tests/lfbprof/0000755000175000017500000000000010040503214015612 5ustar guillemguillemvgabios-0.7a/tests/lfbprof/Makefile0000644000175000017500000000021307434275445017277 0ustar guillemguillem# Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW lfbprof.exe: lfbprof.c lfbprof.h wcl386 -zq -s -d2 lfbprof.c vgabios-0.7a/tests/lfbprof/lfbprof.c0000644000175000017500000005050710040503214017417 0ustar guillemguillem/**************************************************************************** * * VBE 2.0 Linear Framebuffer Profiler * By Kendall Bennett and Brian Hook * * Filename: LFBPROF.C * Language: ANSI C * Environment: Watcom C/C++ 10.0a with DOS4GW * * Description: Simple program to profile the speed of screen clearing * and full screen BitBlt operations using a VESA VBE 2.0 * linear framebuffer from 32 bit protected mode. * * For simplicity, this program only supports 256 color * SuperVGA video modes that support a linear framebuffer. * * * 2002/02/18: Jeroen Janssen * - fixed unsigned short for mode list (-1 != 0xffff otherwise) * - fixed LfbMapRealPointer macro mask problem (some modes were skipped) * ****************************************************************************/ #include #include #include #include #include #include "lfbprof.h" /*---------------------------- Global Variables ---------------------------*/ int VESABuf_len = 1024; /* Length of VESABuf */ int VESABuf_sel = 0; /* Selector for VESABuf */ int VESABuf_rseg; /* Real mode segment of VESABuf */ unsigned short modeList[50]; /* List of available VBE modes */ float clearsPerSec; /* Number of clears per second */ float clearsMbPerSec; /* Memory transfer for clears */ float bitBltsPerSec; /* Number of BitBlt's per second */ float bitBltsMbPerSec; /* Memory transfer for bitblt's */ int xres,yres; /* Video mode resolution */ int bytesperline; /* Bytes per scanline for mode */ long imageSize; /* Length of the video image */ char *LFBPtr; /* Pointer to linear framebuffer */ /*------------------------- DPMI interface routines -----------------------*/ void DPMI_allocRealSeg(int size,int *sel,int *r_seg) /**************************************************************************** * * Function: DPMI_allocRealSeg * Parameters: size - Size of memory block to allocate * sel - Place to return protected mode selector * r_seg - Place to return real mode segment * * Description: Allocates a block of real mode memory using DPMI services. * This routine returns both a protected mode selector and * real mode segment for accessing the memory block. * ****************************************************************************/ { union REGS r; r.w.ax = 0x100; /* DPMI allocate DOS memory */ r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */ int386(0x31, &r, &r); if (r.w.cflag) FatalError("DPMI_allocRealSeg failed!"); *sel = r.w.dx; /* Protected mode selector */ *r_seg = r.w.ax; /* Real mode segment */ } void DPMI_freeRealSeg(unsigned sel) /**************************************************************************** * * Function: DPMI_allocRealSeg * Parameters: sel - Protected mode selector of block to free * * Description: Frees a block of real mode memory. * ****************************************************************************/ { union REGS r; r.w.ax = 0x101; /* DPMI free DOS memory */ r.w.dx = sel; /* DX := selector from 0x100 */ int386(0x31, &r, &r); } typedef struct { long edi; long esi; long ebp; long reserved; long ebx; long edx; long ecx; long eax; short flags; short es,ds,fs,gs,ip,cs,sp,ss; } _RMREGS; #define IN(reg) rmregs.e##reg = in->x.reg #define OUT(reg) out->x.reg = rmregs.e##reg int DPMI_int86(int intno, RMREGS *in, RMREGS *out) /**************************************************************************** * * Function: DPMI_int86 * Parameters: intno - Interrupt number to issue * in - Pointer to structure for input registers * out - Pointer to structure for output registers * Returns: Value returned by interrupt in AX * * Description: Issues a real mode interrupt using DPMI services. * ****************************************************************************/ { _RMREGS rmregs; union REGS r; struct SREGS sr; memset(&rmregs, 0, sizeof(rmregs)); IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); segread(&sr); r.w.ax = 0x300; /* DPMI issue real interrupt */ r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds; r.x.edi = (unsigned)&rmregs; int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); out->x.cflag = rmregs.flags & 0x1; return out->x.ax; } int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs) /**************************************************************************** * * Function: DPMI_int86 * Parameters: intno - Interrupt number to issue * in - Pointer to structure for input registers * out - Pointer to structure for output registers * sregs - Values to load into segment registers * Returns: Value returned by interrupt in AX * * Description: Issues a real mode interrupt using DPMI services. * ****************************************************************************/ { _RMREGS rmregs; union REGS r; struct SREGS sr; memset(&rmregs, 0, sizeof(rmregs)); IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); rmregs.es = sregs->es; rmregs.ds = sregs->ds; segread(&sr); r.w.ax = 0x300; /* DPMI issue real interrupt */ r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds; r.x.edi = (unsigned)&rmregs; int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); sregs->es = rmregs.es; sregs->cs = rmregs.cs; sregs->ss = rmregs.ss; sregs->ds = rmregs.ds; out->x.cflag = rmregs.flags & 0x1; return out->x.ax; } int DPMI_allocSelector(void) /**************************************************************************** * * Function: DPMI_allocSelector * Returns: Newly allocated protected mode selector * * Description: Allocates a new protected mode selector using DPMI * services. This selector has a base address and limit of 0. * ****************************************************************************/ { int sel; union REGS r; r.w.ax = 0; /* DPMI allocate selector */ r.w.cx = 1; /* Allocate a single selector */ int386(0x31, &r, &r); if (r.x.cflag) FatalError("DPMI_allocSelector() failed!"); sel = r.w.ax; r.w.ax = 9; /* DPMI set access rights */ r.w.bx = sel; r.w.cx = 0x8092; /* 32 bit page granular */ int386(0x31, &r, &r); return sel; } long DPMI_mapPhysicalToLinear(long physAddr,long limit) /**************************************************************************** * * Function: DPMI_mapPhysicalToLinear * Parameters: physAddr - Physical memory address to map * limit - Length-1 of physical memory region to map * Returns: Starting linear address for mapped memory * * Description: Maps a section of physical memory into the linear address * space of a process using DPMI calls. Note that this linear * address cannot be used directly, but must be used as the * base address for a selector. * ****************************************************************************/ { union REGS r; r.w.ax = 0x800; /* DPMI map physical to linear */ r.w.bx = physAddr >> 16; r.w.cx = physAddr & 0xFFFF; r.w.si = limit >> 16; r.w.di = limit & 0xFFFF; int386(0x31, &r, &r); if (r.x.cflag) FatalError("DPMI_mapPhysicalToLinear() failed!"); return ((long)r.w.bx << 16) + r.w.cx; } void DPMI_setSelectorBase(int sel,long linAddr) /**************************************************************************** * * Function: DPMI_setSelectorBase * Parameters: sel - Selector to change base address for * linAddr - Linear address used for new base address * * Description: Sets the base address for the specified selector. * ****************************************************************************/ { union REGS r; r.w.ax = 7; /* DPMI set selector base address */ r.w.bx = sel; r.w.cx = linAddr >> 16; r.w.dx = linAddr & 0xFFFF; int386(0x31, &r, &r); if (r.x.cflag) FatalError("DPMI_setSelectorBase() failed!"); } void DPMI_setSelectorLimit(int sel,long limit) /**************************************************************************** * * Function: DPMI_setSelectorLimit * Parameters: sel - Selector to change limit for * limit - Limit-1 for the selector * * Description: Sets the memory limit for the specified selector. * ****************************************************************************/ { union REGS r; r.w.ax = 8; /* DPMI set selector limit */ r.w.bx = sel; r.w.cx = limit >> 16; r.w.dx = limit & 0xFFFF; int386(0x31, &r, &r); if (r.x.cflag) FatalError("DPMI_setSelectorLimit() failed!"); } /*-------------------------- VBE Interface routines -----------------------*/ void FatalError(char *msg) { fprintf(stderr,"%s\n", msg); exit(1); } static void ExitVBEBuf(void) { DPMI_freeRealSeg(VESABuf_sel); } void VBE_initRMBuf(void) /**************************************************************************** * * Function: VBE_initRMBuf * Description: Initialises the VBE transfer buffer in real mode memory. * This routine is called by the VESAVBE module every time * it needs to use the transfer buffer, so we simply allocate * it once and then return. * ****************************************************************************/ { if (!VESABuf_sel) { DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg); atexit(ExitVBEBuf); } } void VBE_callESDI(RMREGS *regs, void *buffer, int size) /**************************************************************************** * * Function: VBE_callESDI * Parameters: regs - Registers to load when calling VBE * buffer - Buffer to copy VBE info block to * size - Size of buffer to fill * * Description: Calls the VESA VBE and passes in a buffer for the VBE to * store information in, which is then copied into the users * buffer space. This works in protected mode as the buffer * passed to the VESA VBE is allocated in conventional * memory, and is then copied into the users memory block. * ****************************************************************************/ { RMSREGS sregs; VBE_initRMBuf(); sregs.es = VESABuf_rseg; regs->x.di = 0; _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size); DPMI_int86x(0x10, regs, regs, &sregs); _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size); } int VBE_detect(void) /**************************************************************************** * * Function: VBE_detect * Parameters: vgaInfo - Place to store the VGA information block * Returns: VBE version number, or 0 if not detected. * * Description: Detects if a VESA VBE is out there and functioning * correctly. If we detect a VBE interface we return the * VGAInfoBlock returned by the VBE and the VBE version number. * ****************************************************************************/ { RMREGS regs; unsigned short *p1,*p2; VBE_vgaInfo vgaInfo; /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows * that we have passed a 512 byte extended block to it, and wish * the extended information to be filled in. */ strncpy(vgaInfo.VESASignature,"VBE2",4); /* Get the SuperVGA Information block */ regs.x.ax = 0x4F00; VBE_callESDI(®s, &vgaInfo, sizeof(VBE_vgaInfo)); if (regs.x.ax != 0x004F) return 0; if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0) return 0; /* Now that we have detected a VBE interface, copy the list of available * video modes into our local buffer. We *must* copy this mode list, * since the VBE will build the mode list in the VBE_vgaInfo buffer * that we have passed, so the next call to the VBE will trash the * list of modes. */ printf("videomodeptr %x\n",vgaInfo.VideoModePtr); p1 = LfbMapRealPointer(vgaInfo.VideoModePtr); p2 = modeList; while (*p1 != -1) { printf("found mode %x\n",*p1); *p2++ = *p1++; } *p2 = -1; return vgaInfo.VESAVersion; } int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo) /**************************************************************************** * * Function: VBE_getModeInfo * Parameters: mode - VBE mode to get information for * modeInfo - Place to store VBE mode information * Returns: 1 on success, 0 if function failed. * * Description: Obtains information about a specific video mode from the * VBE. You should use this function to find the video mode * you wish to set, as the new VBE 2.0 mode numbers may be * completely arbitrary. * ****************************************************************************/ { RMREGS regs; regs.x.ax = 0x4F01; /* Get mode information */ regs.x.cx = mode; VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); if (regs.x.ax != 0x004F) return 0; if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0) return 0; return 1; } void VBE_setVideoMode(int mode) /**************************************************************************** * * Function: VBE_setVideoMode * Parameters: mode - VBE mode number to initialise * ****************************************************************************/ { RMREGS regs; regs.x.ax = 0x4F02; regs.x.bx = mode; DPMI_int86(0x10,®s,®s); } /*-------------------- Application specific routines ----------------------*/ void *GetPtrToLFB(long physAddr) /**************************************************************************** * * Function: GetPtrToLFB * Parameters: physAddr - Physical memory address of linear framebuffer * Returns: Far pointer to the linear framebuffer memory * ****************************************************************************/ { int sel; long linAddr,limit = (4096 * 1024) - 1; // sel = DPMI_allocSelector(); linAddr = DPMI_mapPhysicalToLinear(physAddr,limit); // DPMI_setSelectorBase(sel,linAddr); // DPMI_setSelectorLimit(sel,limit); // return MK_FP(sel,0); return (void*)linAddr; } void AvailableModes(void) /**************************************************************************** * * Function: AvailableModes * * Description: Display a list of available LFB mode resolutions. * ****************************************************************************/ { unsigned short *p; VBE_modeInfo modeInfo; printf("Usage: LFBPROF \n\n"); printf("Available 256 color video modes:\n"); for (p = modeList; *p != -1; p++) { if (VBE_getModeInfo(*p, &modeInfo)) { /* Filter out only 8 bit linear framebuffer modes */ if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) continue; if (modeInfo.MemoryModel != vbeMemPK || modeInfo.BitsPerPixel != 8 || modeInfo.NumberOfPlanes != 1) continue; printf(" %4d x %4d %d bits per pixel\n", modeInfo.XResolution, modeInfo.YResolution, modeInfo.BitsPerPixel); } } exit(1); } void InitGraphics(int x,int y) /**************************************************************************** * * Function: InitGraphics * Parameters: x,y - Requested video mode resolution * * Description: Initialise the specified video mode. We search through * the list of available video modes for one that matches * the resolution and color depth are are looking for. * ****************************************************************************/ { unsigned short *p; VBE_modeInfo modeInfo; printf("InitGraphics\n"); for (p = modeList; *p != -1; p++) { if (VBE_getModeInfo(*p, &modeInfo)) { /* Filter out only 8 bit linear framebuffer modes */ if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) continue; if (modeInfo.MemoryModel != vbeMemPK || modeInfo.BitsPerPixel != 8 || modeInfo.NumberOfPlanes != 1) continue; if (modeInfo.XResolution != x || modeInfo.YResolution != y) continue; xres = x; yres = y; bytesperline = modeInfo.BytesPerScanLine; imageSize = bytesperline * yres; VBE_setVideoMode(*p | vbeUseLFB); LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr); return; } } printf("Valid video mode not found\n"); exit(1); } void EndGraphics(void) /**************************************************************************** * * Function: EndGraphics * * Description: Restores text mode. * ****************************************************************************/ { RMREGS regs; printf("EndGraphics\n"); regs.x.ax = 0x3; DPMI_int86(0x10, ®s, ®s); } void ProfileMode(void) /**************************************************************************** * * Function: ProfileMode * * Description: Profiles framebuffer performance for simple screen clearing * and for copying from system memory to video memory (BitBlt). * This routine thrashes the CPU cache by cycling through * enough system memory buffers to invalidate the entire * CPU external cache before re-using the first memory buffer * again. * ****************************************************************************/ { int i,numClears,numBlts,maxImages; long startTicks,endTicks; void *image[10],*dst; printf("ProfileMode\n"); /* Profile screen clearing operation */ startTicks = LfbGetTicks(); numClears = 0; while ((LfbGetTicks() - startTicks) < 182) LfbMemset(LFBPtr,numClears++,imageSize); endTicks = LfbGetTicks(); clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925); clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0; /* Profile system memory to video memory copies */ maxImages = ((512 * 1024U) / imageSize) + 2; for (i = 0; i < maxImages; i++) { image[i] = malloc(imageSize); if (image[i] == NULL) FatalError("Not enough memory to profile BitBlt!"); memset(image[i],i+1,imageSize); } startTicks = LfbGetTicks(); numBlts = 0; while ((LfbGetTicks() - startTicks) < 182) LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize); endTicks = LfbGetTicks(); bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925); bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0; } void main(int argc, char *argv[]) { if (VBE_detect() < 0x200) FatalError("This program requires VBE 2.0; Please install UniVBE 5.1."); if (argc != 3) AvailableModes(); /* Display available modes */ InitGraphics(atoi(argv[1]),atoi(argv[2])); /* Start graphics */ ProfileMode(); /* Profile the video mode */ EndGraphics(); /* Restore text mode */ printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres); printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec); printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec); } vgabios-0.7a/tests/lfbprof/lfbprof.h0000644000175000017500000001410707434277627017455 0ustar guillemguillem/**************************************************************************** * * VBE 2.0 Linear Framebuffer Profiler * By Kendall Bennett and Brian Hook * * Filename: LFBPROF.H * Language: ANSI C * Environment: Watcom C/C++ 10.0a with DOS4GW * * Description: Header file for the LFBPROF.C progam. * ****************************************************************************/ #ifndef __LFBPROF_H #define __LFBPROF_H /*---------------------- Macros and type definitions ----------------------*/ #pragma pack(1) /* SuperVGA information block */ typedef struct { char VESASignature[4]; /* 'VESA' 4 byte signature */ short VESAVersion; /* VBE version number */ long OemStringPtr; /* Pointer to OEM string */ long Capabilities; /* Capabilities of video card */ long VideoModePtr; /* Pointer to supported modes */ short TotalMemory; /* Number of 64kb memory blocks */ /* VBE 2.0 extensions */ short OemSoftwareRev; /* OEM Software revision number */ long OemVendorNamePtr; /* Pointer to Vendor Name string */ long OemProductNamePtr; /* Pointer to Product Name string */ long OemProductRevPtr; /* Pointer to Product Revision str */ char reserved[222]; /* Pad to 256 byte block size */ char OemDATA[256]; /* Scratch pad for OEM data */ } VBE_vgaInfo; /* SuperVGA mode information block */ typedef struct { short ModeAttributes; /* Mode attributes */ char WinAAttributes; /* Window A attributes */ char WinBAttributes; /* Window B attributes */ short WinGranularity; /* Window granularity in k */ short WinSize; /* Window size in k */ short WinASegment; /* Window A segment */ short WinBSegment; /* Window B segment */ long WinFuncPtr; /* Pointer to window function */ short BytesPerScanLine; /* Bytes per scanline */ short XResolution; /* Horizontal resolution */ short YResolution; /* Vertical resolution */ char XCharSize; /* Character cell width */ char YCharSize; /* Character cell height */ char NumberOfPlanes; /* Number of memory planes */ char BitsPerPixel; /* Bits per pixel */ char NumberOfBanks; /* Number of CGA style banks */ char MemoryModel; /* Memory model type */ char BankSize; /* Size of CGA style banks */ char NumberOfImagePages; /* Number of images pages */ char res1; /* Reserved */ char RedMaskSize; /* Size of direct color red mask */ char RedFieldPosition; /* Bit posn of lsb of red mask */ char GreenMaskSize; /* Size of direct color green mask */ char GreenFieldPosition; /* Bit posn of lsb of green mask */ char BlueMaskSize; /* Size of direct color blue mask */ char BlueFieldPosition; /* Bit posn of lsb of blue mask */ char RsvdMaskSize; /* Size of direct color res mask */ char RsvdFieldPosition; /* Bit posn of lsb of res mask */ char DirectColorModeInfo; /* Direct color mode attributes */ /* VBE 2.0 extensions */ long PhysBasePtr; /* Physical address for linear buf */ long OffScreenMemOffset; /* Pointer to start of offscreen mem*/ short OffScreenMemSize; /* Amount of offscreen mem in 1K's */ char res2[206]; /* Pad to 256 byte block size */ } VBE_modeInfo; #define vbeMemPK 4 /* Packed Pixel memory model */ #define vbeUseLFB 0x4000 /* Enable linear framebuffer mode */ /* Flags for the mode attributes returned by VBE_getModeInfo. If * vbeMdNonBanked is set to 1 and vbeMdLinear is also set to 1, then only * the linear framebuffer mode is available. */ #define vbeMdAvailable 0x0001 /* Video mode is available */ #define vbeMdColorMode 0x0008 /* Mode is a color video mode */ #define vbeMdGraphMode 0x0010 /* Mode is a graphics mode */ #define vbeMdNonBanked 0x0040 /* Banked mode is not supported */ #define vbeMdLinear 0x0080 /* Linear mode supported */ /* Structures for issuing real mode interrupts with DPMI */ struct _RMWORDREGS { unsigned short ax, bx, cx, dx, si, di, cflag; }; struct _RMBYTEREGS { unsigned char al, ah, bl, bh, cl, ch, dl, dh; }; typedef union { struct _RMWORDREGS x; struct _RMBYTEREGS h; } RMREGS; typedef struct { unsigned short es; unsigned short cs; unsigned short ss; unsigned short ds; } RMSREGS; /* Inline assembler block fill/move routines */ void LfbMemset(void *p,int c,int n); #pragma aux LfbMemset = \ "shr ecx,2" \ "xor eax,eax" \ "mov al,bl" \ "shl ebx,8" \ "or ax,bx" \ "mov ebx,eax" \ "shl ebx,16" \ "or eax,ebx" \ "rep stosd" \ parm [edi] [ebx] [ecx]; void LfbMemcpy(void *dst,void *src,int n); #pragma aux LfbMemcpy = \ "shr ecx,2" \ "rep movsd" \ parm [edi] [esi] [ecx]; /* Map a real mode pointer into address space */ #define LfbMapRealPointer(p) (void*)(((unsigned)((p) & 0xFFFF0000) >> 12) + ((p) & 0xFFFF)) /* Get the current timer tick count */ #define LfbGetTicks() *((long*)0x46C) #pragma pack() #endif /* __LFBPROF_H */ vgabios-0.7a/biossums.c0000644000175000017500000001626711011512306015043 0ustar guillemguillem/* biossums.c --- written by Eike W. for the Bochs BIOS */ /* adapted for the LGPL'd VGABIOS by vruppert */ /* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include typedef unsigned char byte; void check( int value, char* message ); #define MAX_BIOS_DATA 0x10000 long chksum_bios_get_offset( byte* data, long offset ); byte chksum_bios_calc_value( byte* data, long offset ); byte chksum_bios_get_value( byte* data, long offset ); void chksum_bios_set_value( byte* data, long offset, byte value ); #define PMID_LEN 20 #define PMID_CHKSUM 19 long chksum_pmid_get_offset( byte* data, long offset ); byte chksum_pmid_calc_value( byte* data, long offset ); byte chksum_pmid_get_value( byte* data, long offset ); void chksum_pmid_set_value( byte* data, long offset, byte value ); #define PCIR_LEN 24 long chksum_pcir_get_offset( byte* data, long offset ); byte bios_data[MAX_BIOS_DATA]; long bios_len; int main(int argc, char* argv[]) { FILE* stream; long offset, tmp_offset, pcir_offset; byte bios_len_byte, cur_val = 0, new_val = 0; int hits, modified; if (argc != 2) { printf( "Error. Need a file-name as an argument.\n" ); exit( EXIT_FAILURE ); } if ((stream = fopen(argv[1], "rb")) == NULL) { printf("Error opening %s for reading.\n", argv[1]); exit(EXIT_FAILURE); } memset(bios_data, 0, MAX_BIOS_DATA); bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream); if (bios_len > MAX_BIOS_DATA) { printf("Error reading max. 65536 Bytes from %s.\n", argv[1]); fclose(stream); exit(EXIT_FAILURE); } fclose(stream); modified = 0; if (bios_len < 0x8000) { bios_len = 0x8000; modified = 1; } else if ((bios_len & 0x1FF) != 0) { bios_len = (bios_len + 0x200) & ~0x1FF; modified = 1; } bios_len_byte = (byte)(bios_len / 512); if (bios_len_byte != bios_data[2]) { if (modified == 0) { bios_len += 0x200; } bios_data[2] = (byte)(bios_len / 512); modified = 1; } hits = 0; offset = 0L; while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) { offset = tmp_offset; cur_val = chksum_pmid_get_value( bios_data, offset ); new_val = chksum_pmid_calc_value( bios_data, offset ); printf( "\nPMID entry at: 0x%4lX\n", offset ); printf( "Current checksum: 0x%02X\n", cur_val ); printf( "Calculated checksum: 0x%02X ", new_val ); hits++; } if ((hits == 1) && (cur_val != new_val)) { printf("Setting checksum."); chksum_pmid_set_value( bios_data, offset, new_val ); if (modified == 0) { bios_len += 0x200; bios_data[2]++; } modified = 1; } if (hits >= 2) { printf( "Multiple PMID entries! No checksum set." ); } if (hits) { printf("\n"); } offset = 0L; pcir_offset = chksum_pcir_get_offset( bios_data, offset ); if (pcir_offset != -1L) { if (bios_data[pcir_offset + 16] != bios_data[2]) { bios_data[pcir_offset + 16] = bios_data[2]; if (modified == 0) { bios_len += 0x200; bios_data[2]++; bios_data[pcir_offset + 16]++; } modified = 1; } } offset = 0L; do { offset = chksum_bios_get_offset(bios_data, offset); cur_val = chksum_bios_get_value(bios_data, offset); new_val = chksum_bios_calc_value(bios_data, offset); if ((cur_val != new_val) && (modified == 0)) { bios_len += 0x200; bios_data[2]++; if (pcir_offset != -1L) { bios_data[pcir_offset + 16]++; } modified = 1; } else { printf("\nBios checksum at: 0x%4lX\n", offset); printf("Current checksum: 0x%02X\n", cur_val); printf("Calculated checksum: 0x%02X ", new_val); if (cur_val != new_val) { printf("Setting checksum."); chksum_bios_set_value(bios_data, offset, new_val); cur_val = new_val; modified = 1; } printf( "\n" ); } } while (cur_val != new_val); if (modified == 1) { if ((stream = fopen( argv[1], "wb")) == NULL) { printf("Error opening %s for writing.\n", argv[1]); exit(EXIT_FAILURE); } if (fwrite(bios_data, 1, bios_len, stream) < bios_len) { printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]); fclose(stream); exit(EXIT_FAILURE); } fclose(stream); } return (EXIT_SUCCESS); } void check( int okay, char* message ) { if( !okay ) { printf( "\n\nError. %s.\n", message ); exit( EXIT_FAILURE ); } } long chksum_bios_get_offset( byte* data, long offset ) { return (bios_len - 1); } byte chksum_bios_calc_value( byte* data, long offset ) { int i; byte sum; sum = 0; for( i = 0; i < offset; i++ ) { sum = sum + *( data + i ); } sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ return( sum ); } byte chksum_bios_get_value( byte* data, long offset ) { return( *( data + offset ) ); } void chksum_bios_set_value( byte* data, long offset, byte value ) { *( data + offset ) = value; } byte chksum_pmid_calc_value( byte* data, long offset ) { int i; int len; byte sum; len = PMID_LEN; check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" ); sum = 0; for( i = 0; i < len; i++ ) { if( i != PMID_CHKSUM ) { sum = sum + *( data + offset + i ); } } sum = -sum; return( sum ); } long chksum_pmid_get_offset( byte* data, long offset ) { long result = -1L; while ((offset + PMID_LEN) < (bios_len - 1)) { offset = offset + 1; if( *( data + offset + 0 ) == 'P' && \ *( data + offset + 1 ) == 'M' && \ *( data + offset + 2 ) == 'I' && \ *( data + offset + 3 ) == 'D' ) { result = offset; break; } } return( result ); } byte chksum_pmid_get_value( byte* data, long offset ) { check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); return( *( data + offset + PMID_CHKSUM ) ); } void chksum_pmid_set_value( byte* data, long offset, byte value ) { check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); *( data + offset + PMID_CHKSUM ) = value; } long chksum_pcir_get_offset( byte* data, long offset ) { long result = -1L; while ((offset + PCIR_LEN) < (bios_len - 1)) { offset = offset + 1; if( *( data + offset + 0 ) == 'P' && \ *( data + offset + 1 ) == 'C' && \ *( data + offset + 2 ) == 'I' && \ *( data + offset + 3 ) == 'R' ) { result = offset; break; } } return( result ); }