📄 vgabios.c
字号:
mov al, cl out dx, al pop dx pop ax retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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_DATAset_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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_normalset_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, 2set_dac_16_page: and bh, #0x0f mov al, bh out dx, alset_actl_normal: mov al, #0x20 out dx, al pop dx pop bx pop ax retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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_DATAread_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_set_pel_mask: push ax push dx mov dx, # VGAREG_PEL_MASK mov al, bl out dx, al pop dx pop ax retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_read_pel_mask: push ax push dx mov dx, # VGAREG_PEL_MASK in al, dx mov bl, al pop dx pop ax retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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, 2get_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 retASM_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, axASM_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, axASM_END}ASM_STARTidiv_u: xor dx,dx div bx retASM_ENDstatic 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<CX;i++) { src = BP + i * BH; dest = blockaddr + (DX + i) * 32; memcpyb(0xA000, dest, ES, src, BH); } release_font_access(); if(AL>=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_STARTbiosfn_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 retASM_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;{#ifdef DEBUG unimplemented();#endif}static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL;{#ifdef DEBUG unimplemented();#endif}static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL;{#ifdef DEBUG unimplemented();#endif}static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL;{#ifdef DEBUG unimplemented();#endif}static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL;{#ifdef DEBUG unimplemented();#endif}// --------------------------------------------------------------------------------------------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_STARTbiosfn_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, #0x01mode_ega_color: pop ax pop ds retASM_END// --------------------------------------------------------------------------------------------static void biosfn_alternate_prtsc(){#ifdef DEBUG unimplemented();#endif}// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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_retcodevert_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_resvert_res_350: ; reset modeset ctl bit 7 and bit 4 ; set switches bit 3-0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -