📄 vgabios.c
字号:
set_intensity_loop: mov dx, # VGAREG_ACTL_ADDRESS mov al, cl out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx and al, #0xef or al, bl mov dx, # VGAREG_ACTL_ADDRESS out dx, al inc cl cmp cl, #0x04 jne set_intensity_loop mov al, #0x20 out dx, al pop dx pop cx pop bx pop ax retbiosfn_set_palette: push ax push bx push cx push dx mov dx, # VGAREG_ACTL_RESET in al, dx mov cl, #0x01 and bl, #0x01set_cga_palette_loop: mov dx, # VGAREG_ACTL_ADDRESS mov al, cl out dx, al mov dx, # VGAREG_ACTL_READ_DATA in al, dx and al, #0xfe or al, bl mov dx, # VGAREG_ACTL_ADDRESS out dx, al inc cl cmp cl, #0x04 jne set_cga_palette_loop mov al, #0x20 out dx, al pop dx pop cx pop bx pop ax retASM_END// --------------------------------------------------------------------------------------------static void biosfn_write_pixel (BH,AL,CX,DX) Bit8u BH;Bit8u AL;Bit16u CX;Bit16u DX;{ Bit8u mode,line,mask,attr,data; Bit16u addr; // 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); 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, axASM_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=video_param_table[line_to_vpti[line]].cheight; 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) { biosfn_scroll(0x01,0x07,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_STARTbiosfn_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_group_10: cmp al, #0x00 jne int10_test_1001 jmp biosfn_set_single_palette_regint10_test_1001: cmp al, #0x01 jne int10_test_1002 jmp biosfn_set_overscan_border_colorint10_test_1002: cmp al, #0x02 jne int10_test_1003 jmp biosfn_set_all_palette_regint10_test_1003: cmp al, #0x03 jne int10_test_1007 jmp biosfn_toggle_intensityint10_test_1007: cmp al, #0x07 jne int10_test_1008 jmp biosfn_get_single_palette_regint10_test_1008: cmp al, #0x08 jne int10_test_1009 jmp biosfn_read_overscan_border_colorint10_test_1009: cmp al, #0x09 jne int10_test_1010 jmp biosfn_get_all_palette_regint10_test_1010: cmp al, #0x10 jne int10_test_1012 jmp biosfn_set_single_dac_regint10_test_1012: cmp al, #0x12 jne int10_test_1013 jmp biosfn_set_all_dac_regint10_test_1013: cmp al, #0x13 jne int10_test_1015 jmp biosfn_select_video_dac_color_pageint10_test_1015: cmp al, #0x15 jne int10_test_1017 jmp biosfn_read_single_dac_regint10_test_1017: cmp al, #0x17 jne int10_test_1018 jmp biosfn_read_all_dac_regint10_test_1018: cmp al, #0x18 jne int10_test_1019 jmp biosfn_set_pel_maskint10_test_1019: cmp al, #0x19 jne int10_test_101A jmp biosfn_read_pel_maskint10_test_101A: cmp al, #0x1a jne int10_group_10_unknown jmp biosfn_read_video_dac_stateint10_group_10_unknown:#ifdef DEBUG call _unknown#endif retbiosfn_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 axno_actl_reg1: retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_set_overscan_border_color: push bx mov bl, #0x11 call biosfn_set_single_palette_reg pop bx retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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_ADDRESSset_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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 axno_actl_reg2: retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_get_all_palette_reg: push ax push bx push cx push dx mov bx, dx mov cl, #0x00get_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 retASM_END// --------------------------------------------------------------------------------------------ASM_STARTbiosfn_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -