📄 vbe.c
字号:
mov dx, # VGAREG_VGA_CRTC_ADDRESS mov ah, bl mov al, #0x13 out dx, ax pop dx pop bx pop ax retdispi_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 retdispi_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 retdispi_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, #0x02bit8_clear: test ah, #0x02 jz bit9_clear or al, #0x40bit9_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, alvga_compat_end: pop dx pop axASM_END// ModeInfo helper functionstatic 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_ID4 call dispi_set_idno_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 VBEvbe_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_stringno_vbe_flag: mov ax, #0xc000 mov ds, ax mov si, #_no_vbebios_info_string jmp _display_stringASM_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; 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 64b blocks) vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K; 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 { if ((cur_info->info.XResolution <= dispi_get_max_xres()) && (cur_info->info.BitsPerPixel <= dispi_get_max_bpp())) {#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 by display\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;#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; } 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -