diff options
Diffstat (limited to 'qemu/roms/vgabios/vgabios.c')
-rw-r--r-- | qemu/roms/vgabios/vgabios.c | 3923 |
1 files changed, 0 insertions, 3923 deletions
diff --git a/qemu/roms/vgabios/vgabios.c b/qemu/roms/vgabios/vgabios.c deleted file mode 100644 index c1e312b39..000000000 --- a/qemu/roms/vgabios/vgabios.c +++ /dev/null @@ -1,3923 +0,0 @@ -// ============================================================================================ -/* - * 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 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 -#else -#ifdef PCI_VID -.word PCI_VID -.word PCI_DID -#else -#error "Unknown PCI vendor and device id" -#endif -#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 -#endif - inc sp - inc sp - ret - -#if defined(USE_BX_INFO) || defined(DEBUG) -msg_vga_init: -.ascii "VGABios $Id$" -.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 - } -} - -// ============================================================================================ -// -// 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); - - // Set the whole dac always, from 0 - outb(VGAREG_DAC_WRITE_ADDRESS,0x00); - - // From which palette - switch(vga_modes[line].dacmodel) - {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[vga_modes[line].dacmodel]) - {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); - } - } - 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<cheight;i++) - { - memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols); - } - outw(VGAREG_GRDC_ADDRESS, 0x0005); -} - -// -------------------------------------------------------------------------------------------- -static void vgamem_fill_pl4(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+xstart; - outw(VGAREG_GRDC_ADDRESS, 0x0205); - for(i=0;i<cheight;i++) - { - memsetb(0xa000,dest+i*nbcols,attr,cols); - } - outw(VGAREG_GRDC_ADDRESS, 0x0005); -} - -// -------------------------------------------------------------------------------------------- -static void vgamem_copy_cga(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)>>1)+xstart; - dest=((ydest*cheight*nbcols)>>1)+xstart; - for(i=0;i<cheight;i++) - { - if (i & 1) - memcpyb(0xb800,0x2000+dest+(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<cheight;i++) - { - if (i & 1) - memsetb(0xb800,0x2000+dest+(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((i<rul+nblines)||(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); - if (i>rlr) break; - } - } - } - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - 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((i<rul+nblines)||(nblines==0)) - vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); - else - vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight); - if (i>rlr) 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((i<rul+nblines)||(nblines==0)) - vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); - else - vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight); - if (i>rlr) 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<cheight;i++) - { - dest=addr+i*nbcols; - for(j=0;j<8;j++) - { - mask=0x80>>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=video_param_table[line_to_vpti[line]].cheight; - bpp=vga_modes[line].pixbits; - while((count-->0) && (xcurs<nbcols)) - { - 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++; - } - } -} - -// -------------------------------------------------------------------------------------------- -static void biosfn_write_char_only (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; - - while(count-->0) - {write_byte(vga_modes[line].sstart,address,car); - address+=2; - } - } - else - { - // FIXME gfx mode not complete - cheight=video_param_table[line_to_vpti[line]].cheight; - bpp=vga_modes[line].pixbits; - while((count-->0) && (xcurs<nbcols)) - { - 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++; - } - } -} - -// -------------------------------------------------------------------------------------------- -ASM_START -biosfn_group_0B: - cmp bh, #0x00 - je biosfn_set_border_color - cmp bh, #0x01 - je biosfn_set_palette -#ifdef DEBUG - call _unknown -#endif - ret -biosfn_set_border_color: - push ax - push bx - push cx - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov dx, # VGAREG_ACTL_ADDRESS - mov al, #0x00 - out dx, al - mov al, bl - and al, #0x0f - test al, #0x08 - jz set_low_border - add al, #0x08 -set_low_border: - out dx, al - mov cl, #0x01 - and bl, #0x10 -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 - ret -biosfn_set_palette: - push ax - push bx - push cx - push dx - mov dx, # VGAREG_ACTL_RESET - in al, dx - mov cl, #0x01 - and bl, #0x01 -set_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 - ret -ASM_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, 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=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) - { - 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<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_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; -{ -#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_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<format_width; i++) { - nibble = (arg >> (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 |