1 // ============================================================================================
5 // ============================================================================================
7 // Copyright (C) 2001,2002 the LGPL VGABios developers Team
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2 of the License, or (at your option) any later version.
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 // ============================================================================================
25 // This VGA Bios is specific to the plex86/bochs Emulated VGA card.
26 // You can NOT drive any physical vga card with it.
28 // ============================================================================================
30 // This file contains code ripped from :
31 // - rombios.c of plex86
33 // This VGA Bios contains fonts from :
34 // - fntcol16.zip (c) by Joseph Gil avalable at :
35 // ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip
36 // These fonts are public domain
38 // This VGA Bios is based on information taken from :
39 // - Kevin Lawton's vga card emulation for bochs/plex86
40 // - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html
41 // - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/
42 // - Michael Abrash's Graphics Programming Black Book
43 // - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex
44 // - DOSEMU 1.0.1 source code for several tables values and formulas
46 // Thanks for patches, comments and ideas to :
47 // - techt@pikeonline.net
49 // ============================================================================================
60 static Bit8u
read_byte();
61 static Bit16u
read_word();
62 static void write_byte();
63 static void write_word();
69 static Bit16u
get_SS();
73 static void unimplemented();
74 static void unknown();
76 static Bit8u
find_vga_entry();
78 static void memsetb();
79 static void memsetw();
80 static void memcpyb();
81 static void memcpyw();
83 static void biosfn_set_video_mode();
84 static void biosfn_set_cursor_shape();
85 static void biosfn_set_cursor_pos();
86 static void biosfn_get_cursor_pos();
87 static void biosfn_set_active_page();
88 static void biosfn_scroll();
89 static void biosfn_read_char_attr();
90 static void biosfn_write_char_attr();
91 static void biosfn_write_char_only();
92 static void biosfn_write_pixel();
93 static void biosfn_read_pixel();
94 static void biosfn_write_teletype();
95 static void biosfn_perform_gray_scale_summing();
96 static void biosfn_load_text_user_pat();
97 static void biosfn_load_text_8_14_pat();
98 static void biosfn_load_text_8_8_pat();
99 static void biosfn_load_text_8_16_pat();
100 static void biosfn_load_gfx_8_8_chars();
101 static void biosfn_load_gfx_user_chars();
102 static void biosfn_load_gfx_8_14_chars();
103 static void biosfn_load_gfx_8_8_dd_chars();
104 static void biosfn_load_gfx_8_16_chars();
105 static void biosfn_get_font_info();
106 static void biosfn_alternate_prtsc();
107 static void biosfn_switch_video_interface();
108 static void biosfn_enable_video_refresh_control();
109 static void biosfn_write_string();
110 static void biosfn_read_state_info();
111 static void biosfn_read_video_state_size();
112 static Bit16u
biosfn_save_video_state();
113 static Bit16u
biosfn_restore_video_state();
114 extern Bit8u video_save_pointer_table
[];
116 // This is for compiling with gcc2 and gcc3
117 #define ASM_START #asm
118 #define ASM_END #endasm
143 .byte
0x55, 0xaa /* BIOS signature, required for BIOS extensions */
145 .byte
0x40 /* BIOS extension length in units of 512 bytes */
150 jmp vgabios_init_func
153 .ascii
"Plex86/Bochs VGABios"
157 // Info from Bart Oldeman
176 .ascii
"(C) 2003 the LGPL VGABios developers Team"
181 .ascii
"This VGA/VBE Bios is released under the GNU LGPL"
187 .ascii
"Please visit :"
189 ;;.ascii
" . http://www.plex86.org"
191 .ascii
" . http://bochs.sourceforge.net"
193 .ascii
" . http://www.nongnu.org/vgabios"
199 ;; ============================================================================================
203 ;; ============================================================================================
209 ;; init basic bios vars
213 ;; init vbe functions
218 SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
224 ;; display splash screen
225 call _display_splash_screen
227 ;; init video mode
and clear the screen
236 call vbe_display_info
241 call cirrus_display_info
251 vgabios_int10_handler
:
266 call biosfn_get_video_mode
281 call biosfn_set_text_block_specifier
288 call biosfn_get_ega_info
293 call biosfn_select_vert_res
298 call biosfn_enable_default_palette_loading
303 call biosfn_enable_video_addressing
308 call biosfn_enable_grayscale_summing
313 call biosfn_enable_cursor_emulation
331 jne int10_test_vbe_05
332 call vbe_biosfn_return_current_mode
336 jne int10_test_vbe_06
337 call vbe_biosfn_display_window_control
341 jne int10_test_vbe_07
342 call vbe_biosfn_set_get_logical_scan_line_length
346 jne int10_test_vbe_08
347 call vbe_biosfn_set_get_display_start
351 jne int10_test_vbe_0A
352 call vbe_biosfn_set_get_dac_palette_format
357 call vbe_biosfn_return_protected_mode_interface
366 ;; We have to set ds to access the right data segment
379 #include "vgatables.h"
380 #include "vgafonts.h"
383 * Boot time harware inits
387 ;; switch to color mode
and enable CPU access
480 lines
392 ;; more than
64k
3C4
/04
400 #if defined(USE_BX_INFO) || defined(DEBUG)
401 mov bx
, #msg_vga_init
409 #if defined(USE_BX_INFO) || defined(DEBUG)
411 .ascii
"VGABios $Id: vgabios.c,v 1.66 2006/07/10 07:47:51 vruppert Exp $"
416 // --------------------------------------------------------------------------------------------
418 * Boot time bios area inits
423 mov ax
, # BIOSMEM_SEG
426 ;; init detected hardware BIOS Area
427 mov bx
, # BIOSMEM_INITIAL_MODE
430 ;; set
80x25
color (not clear from RBIL but usual
)
434 ;; Just
for the first int10 find its children
436 ;; the
default char height
437 mov bx
, # BIOSMEM_CHAR_HEIGHT
442 mov bx
, # BIOSMEM_VIDEO_CTL
446 ;; Set the basic screen we have
447 mov bx
, # BIOSMEM_SWITCHES
451 ;; Set the basic modeset options
452 mov bx
, # BIOSMEM_MODESET_CTL
456 ;; Set the
default MSR
457 mov bx
, # BIOSMEM_CURRENT_MSR
464 _video_save_pointer_table
:
465 .word _video_param_table
468 .word
0 /* XXX: fill it */
471 .word
0 /* XXX: fill it */
474 .word
0 /* XXX: fill it */
477 .word
0 /* XXX: fill it */
480 .word
0 /* XXX: fill it */
483 .word
0 /* XXX: fill it */
488 // --------------------------------------------------------------------------------------------
490 * Boot time Splash screen
492 static void display_splash_screen()
496 // --------------------------------------------------------------------------------------------
501 static void display_info()
508 mov si
,#vgabios_version
511 ;;mov si
,#vgabios_copyright
512 ;;call _display_string
514 ;;call _display_string
516 mov si
,#vgabios_license
518 mov si
,#vgabios_website
523 static void display_string()
525 // Get length of string
552 // --------------------------------------------------------------------------------------------
554 static void int10_debugmsg(DI
, SI
, BP
, SP
, BX
, DX
, CX
, AX
, DS
, ES
, FLAGS
)
555 Bit16u DI
, SI
, BP
, SP
, BX
, DX
, CX
, AX
, ES
, DS
, FLAGS
;
557 // 0E is write char...
559 printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX
,CX
,DX
);
563 // --------------------------------------------------------------------------------------------
565 * int10 main dispatcher
567 static void int10_func(DI
, SI
, BP
, SP
, BX
, DX
, CX
, AX
, DS
, ES
, FLAGS
)
568 Bit16u DI
, SI
, BP
, SP
, BX
, DX
, CX
, AX
, ES
, DS
, FLAGS
;
575 biosfn_set_video_mode(GET_AL());
576 switch(GET_AL()&0x7F)
594 biosfn_set_cursor_shape(GET_CH(),GET_CL());
597 biosfn_set_cursor_pos(GET_BH(),DX
);
600 biosfn_get_cursor_pos(GET_BH(),&CX
,&DX
);
603 // Read light pen pos (unimplemented)
613 biosfn_set_active_page(GET_AL());
616 biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP
);
619 biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN
);
622 biosfn_read_char_attr(GET_BH(),&AX
);
625 biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX
);
628 biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX
);
631 biosfn_write_pixel(GET_BH(),GET_AL(),CX
,DX
);
634 biosfn_read_pixel(GET_BH(),CX
,DX
,&AX
);
637 // Ralf Brown Interrupt list is WRONG on bh(page)
638 // We do output only on the current page !
639 biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR
);
642 // All other functions of group AH=0x10 rewritten in assembler
643 biosfn_perform_gray_scale_summing(BX
,CX
);
650 biosfn_load_text_user_pat(GET_AL(),ES
,BP
,CX
,DX
,GET_BL(),GET_BH());
654 biosfn_load_text_8_14_pat(GET_AL(),GET_BL());
658 biosfn_load_text_8_8_pat(GET_AL(),GET_BL());
662 biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
665 biosfn_load_gfx_8_8_chars(ES
,BP
);
668 biosfn_load_gfx_user_chars(ES
,BP
,CX
,GET_BL(),GET_DL());
671 biosfn_load_gfx_8_14_chars(GET_BL());
674 biosfn_load_gfx_8_8_dd_chars(GET_BL());
677 biosfn_load_gfx_8_16_chars(GET_BL());
680 biosfn_get_font_info(GET_BH(),&ES
,&BP
,&CX
,&DX
);
693 biosfn_alternate_prtsc();
696 biosfn_switch_video_interface(GET_AL(),ES
,DX
);
700 biosfn_enable_video_refresh_control(GET_AL());
710 biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX
,GET_DH(),GET_DL(),ES
,BP
);
713 biosfn_read_state_info(BX
,ES
,DI
);
720 biosfn_read_video_state_size(CX
,&BX
);
723 biosfn_save_video_state(CX
,ES
,BX
);
726 biosfn_restore_video_state(CX
,ES
,BX
);
738 if (vbe_has_vbe_display()) {
742 vbe_biosfn_return_controller_information(&AX
,ES
,DI
);
745 vbe_biosfn_return_mode_information(&AX
,CX
,ES
,DI
);
748 vbe_biosfn_set_mode(&AX
,BX
,ES
,DI
);
751 vbe_biosfn_save_restore_state(&AX
, CX
, DX
, ES
, &BX
);
791 // ============================================================================================
795 // ============================================================================================
797 static void biosfn_set_video_mode(mode
) Bit8u mode
;
798 {// mode: Bit 7 is 1 if no clear screen
800 // Should we clear the screen ?
801 Bit8u noclearmem
=mode
&0x80;
802 Bit8u line
,mmask
,*palette
,vpti
;
803 Bit16u i
,twidth
,theightm1
,cheight
;
804 Bit8u modeset_ctl
,video_ctl
,vga_switches
;
808 if (vbe_has_vbe_display()) {
809 dispi_set_enable(VBE_DISPI_DISABLED
);
816 // find the entry in the video modes
817 line
=find_vga_entry(mode
);
820 printf("mode search %02x found line %02x\n",mode
,line
);
826 vpti
=line_to_vpti
[line
];
827 twidth
=video_param_table
[vpti
].twidth
;
828 theightm1
=video_param_table
[vpti
].theightm1
;
829 cheight
=video_param_table
[vpti
].cheight
;
831 // Read the bios vga control
832 video_ctl
=read_byte(BIOSMEM_SEG
,BIOSMEM_VIDEO_CTL
);
834 // Read the bios vga switches
835 vga_switches
=read_byte(BIOSMEM_SEG
,BIOSMEM_SWITCHES
);
837 // Read the bios mode set control
838 modeset_ctl
=read_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
);
840 // Then we know the number of lines
843 // if palette loading (bit 3 of modeset ctl = 0)
844 if((modeset_ctl
&0x08)==0)
846 outb(VGAREG_PEL_MASK
,vga_modes
[line
].pelmask
);
848 // Set the whole dac always, from 0
849 outb(VGAREG_DAC_WRITE_ADDRESS
,0x00);
851 // From which palette
852 switch(vga_modes
[line
].dacmodel
)
866 // Always 256*3 values
867 for(i
=0;i
<0x0100;i
++)
868 {if(i
<=dac_regs
[vga_modes
[line
].dacmodel
])
869 {outb(VGAREG_DAC_DATA
,palette
[(i
*3)+0]);
870 outb(VGAREG_DAC_DATA
,palette
[(i
*3)+1]);
871 outb(VGAREG_DAC_DATA
,palette
[(i
*3)+2]);
874 {outb(VGAREG_DAC_DATA
,0);
875 outb(VGAREG_DAC_DATA
,0);
876 outb(VGAREG_DAC_DATA
,0);
879 if((modeset_ctl
&0x02)==0x02)
881 biosfn_perform_gray_scale_summing(0x00, 0x100);
885 // Reset Attribute Ctl flip-flop
886 inb(VGAREG_ACTL_RESET
);
890 {outb(VGAREG_ACTL_ADDRESS
,i
);
891 outb(VGAREG_ACTL_WRITE_DATA
,video_param_table
[vpti
].actl_regs
[i
]);
893 outb(VGAREG_ACTL_ADDRESS
,0x14);
894 outb(VGAREG_ACTL_WRITE_DATA
,0x00);
897 outb(VGAREG_SEQU_ADDRESS
,0);
898 outb(VGAREG_SEQU_DATA
,0x03);
900 {outb(VGAREG_SEQU_ADDRESS
,i
);
901 outb(VGAREG_SEQU_DATA
,video_param_table
[vpti
].sequ_regs
[i
- 1]);
906 {outb(VGAREG_GRDC_ADDRESS
,i
);
907 outb(VGAREG_GRDC_DATA
,video_param_table
[vpti
].grdc_regs
[i
]);
910 // Set CRTC address VGA or MDA
911 crtc_addr
=vga_modes
[line
].memmodel
==MTEXT
?VGAREG_MDA_CRTC_ADDRESS
:VGAREG_VGA_CRTC_ADDRESS
;
913 // Disable CRTC write protection
914 outw(crtc_addr
,0x0011);
918 outb(crtc_addr
+1,video_param_table
[vpti
].crtc_regs
[i
]);
921 // Set the misc register
922 outb(VGAREG_WRITE_MISC_OUTPUT
,video_param_table
[vpti
].miscreg
);
925 outb(VGAREG_ACTL_ADDRESS
,0x20);
926 inb(VGAREG_ACTL_RESET
);
930 if(vga_modes
[line
].class==TEXT
)
932 memsetw(vga_modes
[line
].sstart
,0,0x0720,0x4000); // 32k
938 memsetw(vga_modes
[line
].sstart
,0,0x0000,0x4000); // 32k
942 outb( VGAREG_SEQU_ADDRESS
, 0x02 );
943 mmask
= inb( VGAREG_SEQU_DATA
);
944 outb( VGAREG_SEQU_DATA
, 0x0f ); // all planes
945 memsetw(vga_modes
[line
].sstart
,0,0x0000,0x8000); // 64k
946 outb( VGAREG_SEQU_DATA
, mmask
);
952 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
,mode
);
953 write_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
,twidth
);
954 write_word(BIOSMEM_SEG
,BIOSMEM_PAGE_SIZE
,*(Bit16u
*)&video_param_table
[vpti
].slength_l
);
955 write_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
,crtc_addr
);
956 write_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
,theightm1
);
957 write_word(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
,cheight
);
958 write_byte(BIOSMEM_SEG
,BIOSMEM_VIDEO_CTL
,(0x60|noclearmem
));
959 write_byte(BIOSMEM_SEG
,BIOSMEM_SWITCHES
,0xF9);
960 write_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
,read_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
)&0x7f);
962 // FIXME We nearly have the good tables. to be reworked
963 write_byte(BIOSMEM_SEG
,BIOSMEM_DCC_INDEX
,0x08); // 8 is VGA should be ok for now
964 write_word(BIOSMEM_SEG
,BIOSMEM_VS_POINTER
, video_save_pointer_table
);
965 write_word(BIOSMEM_SEG
,BIOSMEM_VS_POINTER
+2, 0xc000);
968 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MSR
,0x00); // Unavailable on vanilla vga, but...
969 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAL
,0x00); // Unavailable on vanilla vga, but...
972 if(vga_modes
[line
].class==TEXT
)
974 biosfn_set_cursor_shape(0x06,0x07);
977 // Set cursor pos for page 0..7
979 biosfn_set_cursor_pos(i
,0x0000);
982 biosfn_set_active_page(0x00);
984 // Write the fonts in memory
985 if(vga_modes
[line
].class==TEXT
)
988 ;; copy
and activate
8x16 font
998 // Set the ints 0x1F and 0x43
1000 SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8)
1006 SET_INT_VECTOR(0x43, #0xC000, #_vgafont8)
1011 SET_INT_VECTOR(0x43, #0xC000, #_vgafont14)
1016 SET_INT_VECTOR(0x43, #0xC000, #_vgafont16)
1022 // --------------------------------------------------------------------------------------------
1023 static void biosfn_set_cursor_shape (CH
,CL
)
1025 {Bit16u cheight
,curs
,crtc_addr
;
1032 write_word(BIOSMEM_SEG
,BIOSMEM_CURSOR_TYPE
,curs
);
1034 modeset_ctl
=read_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
);
1035 cheight
= read_word(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
);
1036 if((modeset_ctl
&0x01) && (cheight
>8) && (CL
<8) && (CH
<0x20))
1040 CH
= ((CH
+1) * cheight
/ 8) -1;
1044 CH
= ((CL
+1) * cheight
/ 8) - 2;
1046 CL
= ((CL
+1) * cheight
/ 8) - 1;
1049 // CTRC regs 0x0a and 0x0b
1050 crtc_addr
=read_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
);
1051 outb(crtc_addr
,0x0a);
1052 outb(crtc_addr
+1,CH
);
1053 outb(crtc_addr
,0x0b);
1054 outb(crtc_addr
+1,CL
);
1057 // --------------------------------------------------------------------------------------------
1058 static void biosfn_set_cursor_pos (page
, cursor
)
1059 Bit8u page
;Bit16u cursor
;
1061 Bit8u xcurs
,ycurs
,current
;
1062 Bit16u nbcols
,nbrows
,address
,crtc_addr
;
1064 // Should not happen...
1068 write_word(BIOSMEM_SEG
, BIOSMEM_CURSOR_POS
+2*page
, cursor
);
1070 // Set the hardware cursor
1071 current
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
);
1074 // Get the dimensions
1075 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1076 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1078 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1080 // Calculate the address knowing nbcols nbrows and page num
1081 address
=SCREEN_IO_START(nbcols
,nbrows
,page
)+xcurs
+ycurs
*nbcols
;
1083 // CRTC regs 0x0e and 0x0f
1084 crtc_addr
=read_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
);
1085 outb(crtc_addr
,0x0e);
1086 outb(crtc_addr
+1,(address
&0xff00)>>8);
1087 outb(crtc_addr
,0x0f);
1088 outb(crtc_addr
+1,address
&0x00ff);
1092 // --------------------------------------------------------------------------------------------
1093 static void biosfn_get_cursor_pos (page
,shape
, pos
)
1094 Bit8u page
;Bit16u
*shape
;Bit16u
*pos
;
1099 write_word(ss
, shape
, 0);
1100 write_word(ss
, pos
, 0);
1103 // FIXME should handle VGA 14/16 lines
1104 write_word(ss
,shape
,read_word(BIOSMEM_SEG
,BIOSMEM_CURSOR_TYPE
));
1105 write_word(ss
,pos
,read_word(BIOSMEM_SEG
,BIOSMEM_CURSOR_POS
+page
*2));
1108 // --------------------------------------------------------------------------------------------
1109 static void biosfn_set_active_page (page
)
1112 Bit16u cursor
,dummy
,crtc_addr
;
1113 Bit16u nbcols
,nbrows
,address
;
1119 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1120 line
=find_vga_entry(mode
);
1121 if(line
==0xFF)return;
1123 // Get pos curs pos for the right page
1124 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1126 if(vga_modes
[line
].class==TEXT
)
1128 // Get the dimensions
1129 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1130 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1132 // Calculate the address knowing nbcols nbrows and page num
1133 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
);
1134 write_word(BIOSMEM_SEG
,BIOSMEM_CURRENT_START
,address
);
1137 address
=SCREEN_IO_START(nbcols
,nbrows
,page
);
1141 address
= page
* (*(Bit16u
*)&video_param_table
[line_to_vpti
[line
]].slength_l
);
1144 // CRTC regs 0x0c and 0x0d
1145 crtc_addr
=read_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
);
1146 outb(crtc_addr
,0x0c);
1147 outb(crtc_addr
+1,(address
&0xff00)>>8);
1148 outb(crtc_addr
,0x0d);
1149 outb(crtc_addr
+1,address
&0x00ff);
1151 // And change the BIOS page
1152 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
,page
);
1155 printf("Set active page %02x address %04x\n",page
,address
);
1158 // Display the cursor, now the page is active
1159 biosfn_set_cursor_pos(page
,cursor
);
1162 // --------------------------------------------------------------------------------------------
1163 static void vgamem_copy_pl4(xstart
,ysrc
,ydest
,cols
,nbcols
,cheight
)
1164 Bit8u xstart
;Bit8u ysrc
;Bit8u ydest
;Bit8u cols
;Bit8u nbcols
;Bit8u cheight
;
1169 src
=ysrc
*cheight
*nbcols
+xstart
;
1170 dest
=ydest
*cheight
*nbcols
+xstart
;
1171 outw(VGAREG_GRDC_ADDRESS
, 0x0105);
1172 for(i
=0;i
<cheight
;i
++)
1174 memcpyb(0xa000,dest
+i
*nbcols
,0xa000,src
+i
*nbcols
,cols
);
1176 outw(VGAREG_GRDC_ADDRESS
, 0x0005);
1179 // --------------------------------------------------------------------------------------------
1180 static void vgamem_fill_pl4(xstart
,ystart
,cols
,nbcols
,cheight
,attr
)
1181 Bit8u xstart
;Bit8u ystart
;Bit8u cols
;Bit8u nbcols
;Bit8u cheight
;Bit8u attr
;
1186 dest
=ystart
*cheight
*nbcols
+xstart
;
1187 outw(VGAREG_GRDC_ADDRESS
, 0x0205);
1188 for(i
=0;i
<cheight
;i
++)
1190 memsetb(0xa000,dest
+i
*nbcols
,attr
,cols
);
1192 outw(VGAREG_GRDC_ADDRESS
, 0x0005);
1195 // --------------------------------------------------------------------------------------------
1196 static void vgamem_copy_cga(xstart
,ysrc
,ydest
,cols
,nbcols
,cheight
)
1197 Bit8u xstart
;Bit8u ysrc
;Bit8u ydest
;Bit8u cols
;Bit8u nbcols
;Bit8u cheight
;
1202 src
=((ysrc
*cheight
*nbcols
)>>1)+xstart
;
1203 dest
=((ydest
*cheight
*nbcols
)>>1)+xstart
;
1204 for(i
=0;i
<cheight
;i
++)
1207 memcpyb(0xb800,0x2000+dest
+(i
>>1)*nbcols
,0xb800,0x2000+src
+(i
>>1)*nbcols
,cols
);
1209 memcpyb(0xb800,dest
+(i
>>1)*nbcols
,0xb800,src
+(i
>>1)*nbcols
,cols
);
1213 // --------------------------------------------------------------------------------------------
1214 static void vgamem_fill_cga(xstart
,ystart
,cols
,nbcols
,cheight
,attr
)
1215 Bit8u xstart
;Bit8u ystart
;Bit8u cols
;Bit8u nbcols
;Bit8u cheight
;Bit8u attr
;
1220 dest
=((ystart
*cheight
*nbcols
)>>1)+xstart
;
1221 for(i
=0;i
<cheight
;i
++)
1224 memsetb(0xb800,0x2000+dest
+(i
>>1)*nbcols
,attr
,cols
);
1226 memsetb(0xb800,dest
+(i
>>1)*nbcols
,attr
,cols
);
1230 // --------------------------------------------------------------------------------------------
1231 static void biosfn_scroll (nblines
,attr
,rul
,cul
,rlr
,clr
,page
,dir
)
1232 Bit8u nblines
;Bit8u attr
;Bit8u rul
;Bit8u cul
;Bit8u rlr
;Bit8u clr
;Bit8u page
;Bit8u dir
;
1234 // page == 0xFF if current
1236 Bit8u mode
,line
,cheight
,bpp
,cols
;
1237 Bit16u nbcols
,nbrows
,i
;
1244 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1245 line
=find_vga_entry(mode
);
1246 if(line
==0xFF)return;
1248 // Get the dimensions
1249 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1250 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1252 // Get the current page
1254 page
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
);
1256 if(rlr
>=nbrows
)rlr
=nbrows
-1;
1257 if(clr
>=nbcols
)clr
=nbcols
-1;
1258 if(nblines
>nbrows
)nblines
=0;
1261 if(vga_modes
[line
].class==TEXT
)
1263 // Compute the address
1264 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
);
1266 printf("Scroll, address %04x (%04x %04x %02x)\n",address
,nbrows
,nbcols
,page
);
1269 if(nblines
==0&&rul
==0&&cul
==0&&rlr
==nbrows
-1&&clr
==nbcols
-1)
1271 memsetw(vga_modes
[line
].sstart
,address
,(Bit16u
)attr
*0x100+' ',nbrows
*nbcols
);
1276 {for(i
=rul
;i
<=rlr
;i
++)
1278 if((i
+nblines
>rlr
)||(nblines
==0))
1279 memsetw(vga_modes
[line
].sstart
,address
+(i
*nbcols
+cul
)*2,(Bit16u
)attr
*0x100+' ',cols
);
1281 memcpyw(vga_modes
[line
].sstart
,address
+(i
*nbcols
+cul
)*2,vga_modes
[line
].sstart
,((i
+nblines
)*nbcols
+cul
)*2,cols
);
1285 {for(i
=rlr
;i
>=rul
;i
--)
1287 if((i
<rul
+nblines
)||(nblines
==0))
1288 memsetw(vga_modes
[line
].sstart
,address
+(i
*nbcols
+cul
)*2,(Bit16u
)attr
*0x100+' ',cols
);
1290 memcpyw(vga_modes
[line
].sstart
,address
+(i
*nbcols
+cul
)*2,vga_modes
[line
].sstart
,((i
-nblines
)*nbcols
+cul
)*2,cols
);
1298 // FIXME gfx mode not complete
1299 cheight
=video_param_table
[line_to_vpti
[line
]].cheight
;
1300 switch(vga_modes
[line
].memmodel
)
1304 if(nblines
==0&&rul
==0&&cul
==0&&rlr
==nbrows
-1&&clr
==nbcols
-1)
1306 outw(VGAREG_GRDC_ADDRESS
, 0x0205);
1307 memsetb(vga_modes
[line
].sstart
,0,attr
,nbrows
*nbcols
*cheight
);
1308 outw(VGAREG_GRDC_ADDRESS
, 0x0005);
1313 {for(i
=rul
;i
<=rlr
;i
++)
1315 if((i
+nblines
>rlr
)||(nblines
==0))
1316 vgamem_fill_pl4(cul
,i
,cols
,nbcols
,cheight
,attr
);
1318 vgamem_copy_pl4(cul
,i
+nblines
,i
,cols
,nbcols
,cheight
);
1322 {for(i
=rlr
;i
>=rul
;i
--)
1324 if((i
<rul
+nblines
)||(nblines
==0))
1325 vgamem_fill_pl4(cul
,i
,cols
,nbcols
,cheight
,attr
);
1327 vgamem_copy_pl4(cul
,i
,i
-nblines
,cols
,nbcols
,cheight
);
1334 bpp
=vga_modes
[line
].pixbits
;
1335 if(nblines
==0&&rul
==0&&cul
==0&&rlr
==nbrows
-1&&clr
==nbcols
-1)
1337 memsetb(vga_modes
[line
].sstart
,0,attr
,nbrows
*nbcols
*cheight
*bpp
);
1349 {for(i
=rul
;i
<=rlr
;i
++)
1351 if((i
+nblines
>rlr
)||(nblines
==0))
1352 vgamem_fill_cga(cul
,i
,cols
,nbcols
,cheight
,attr
);
1354 vgamem_copy_cga(cul
,i
+nblines
,i
,cols
,nbcols
,cheight
);
1358 {for(i
=rlr
;i
>=rul
;i
--)
1360 if((i
<rul
+nblines
)||(nblines
==0))
1361 vgamem_fill_cga(cul
,i
,cols
,nbcols
,cheight
,attr
);
1363 vgamem_copy_cga(cul
,i
,i
-nblines
,cols
,nbcols
,cheight
);
1371 printf("Scroll in graphics mode ");
1378 // --------------------------------------------------------------------------------------------
1379 static void biosfn_read_char_attr (page
,car
)
1380 Bit8u page
;Bit16u
*car
;
1381 {Bit16u ss
=get_SS();
1382 Bit8u xcurs
,ycurs
,mode
,line
;
1383 Bit16u nbcols
,nbrows
,address
;
1384 Bit16u cursor
,dummy
;
1387 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1388 line
=find_vga_entry(mode
);
1389 if(line
==0xFF)return;
1391 // Get the cursor pos for the page
1392 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1393 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1395 // Get the dimensions
1396 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1397 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1399 if(vga_modes
[line
].class==TEXT
)
1401 // Compute the address
1402 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
)+(xcurs
+ycurs
*nbcols
)*2;
1404 write_word(ss
,car
,read_word(vga_modes
[line
].sstart
,address
));
1415 // --------------------------------------------------------------------------------------------
1416 static void write_gfx_char_pl4(car
,attr
,xcurs
,ycurs
,nbcols
,cheight
)
1417 Bit8u car
;Bit8u attr
;Bit8u xcurs
;Bit8u ycurs
;Bit8u nbcols
;Bit8u cheight
;
1421 Bit16u addr
,dest
,src
;
1433 addr
=xcurs
+ycurs
*cheight
*nbcols
;
1434 src
= car
* cheight
;
1435 outw(VGAREG_SEQU_ADDRESS
, 0x0f02);
1436 outw(VGAREG_GRDC_ADDRESS
, 0x0205);
1439 outw(VGAREG_GRDC_ADDRESS
, 0x1803);
1443 outw(VGAREG_GRDC_ADDRESS
, 0x0003);
1445 for(i
=0;i
<cheight
;i
++)
1451 outw(VGAREG_GRDC_ADDRESS
, (mask
<< 8) | 0x08);
1452 read_byte(0xa000,dest
);
1453 if(fdata
[src
+i
]&mask
)
1455 write_byte(0xa000,dest
,attr
&0x0f);
1459 write_byte(0xa000,dest
,0x00);
1464 mov dx
, # VGAREG_GRDC_ADDRESS
1474 // --------------------------------------------------------------------------------------------
1475 static void write_gfx_char_cga(car
,attr
,xcurs
,ycurs
,nbcols
,bpp
)
1476 Bit8u car
;Bit8u attr
;Bit8u xcurs
;Bit8u ycurs
;Bit8u nbcols
;Bit8u bpp
;
1478 Bit8u i
,j
,mask
,data
;
1480 Bit16u addr
,dest
,src
;
1483 addr
=(xcurs
*bpp
)+ycurs
*320;
1487 dest
=addr
+(i
>>1)*80;
1488 if (i
& 1) dest
+= 0x2000;
1494 data
= read_byte(0xb800,dest
);
1502 if (fdata
[src
+i
] & mask
)
1506 data
^= (attr
& 0x01) << (7-j
);
1510 data
|= (attr
& 0x01) << (7-j
);
1515 write_byte(0xb800,dest
,data
);
1523 data
= read_byte(0xb800,dest
);
1531 if (fdata
[src
+i
] & mask
)
1535 data
^= (attr
& 0x03) << ((3-j
)*2);
1539 data
|= (attr
& 0x03) << ((3-j
)*2);
1544 write_byte(0xb800,dest
,data
);
1551 // --------------------------------------------------------------------------------------------
1552 static void write_gfx_char_lin(car
,attr
,xcurs
,ycurs
,nbcols
)
1553 Bit8u car
;Bit8u attr
;Bit8u xcurs
;Bit8u ycurs
;Bit8u nbcols
;
1555 Bit8u i
,j
,mask
,data
;
1557 Bit16u addr
,dest
,src
;
1560 addr
=xcurs
*8+ycurs
*nbcols
*64;
1564 dest
=addr
+i
*nbcols
*8;
1569 if (fdata
[src
+i
] & mask
)
1573 write_byte(0xa000,dest
+j
,data
);
1579 // --------------------------------------------------------------------------------------------
1580 static void biosfn_write_char_attr (car
,page
,attr
,count
)
1581 Bit8u car
;Bit8u page
;Bit8u attr
;Bit16u count
;
1583 Bit8u cheight
,xcurs
,ycurs
,mode
,line
,bpp
;
1584 Bit16u nbcols
,nbrows
,address
;
1585 Bit16u cursor
,dummy
;
1588 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1589 line
=find_vga_entry(mode
);
1590 if(line
==0xFF)return;
1592 // Get the cursor pos for the page
1593 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1594 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1596 // Get the dimensions
1597 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1598 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1600 if(vga_modes
[line
].class==TEXT
)
1602 // Compute the address
1603 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
)+(xcurs
+ycurs
*nbcols
)*2;
1605 dummy
=((Bit16u
)attr
<<8)+car
;
1606 memsetw(vga_modes
[line
].sstart
,address
,dummy
,count
);
1610 // FIXME gfx mode not complete
1611 cheight
=video_param_table
[line_to_vpti
[line
]].cheight
;
1612 bpp
=vga_modes
[line
].pixbits
;
1613 while((count
-->0) && (xcurs
<nbcols
))
1615 switch(vga_modes
[line
].memmodel
)
1619 write_gfx_char_pl4(car
,attr
,xcurs
,ycurs
,nbcols
,cheight
);
1622 write_gfx_char_cga(car
,attr
,xcurs
,ycurs
,nbcols
,bpp
);
1625 write_gfx_char_lin(car
,attr
,xcurs
,ycurs
,nbcols
);
1637 // --------------------------------------------------------------------------------------------
1638 static void biosfn_write_char_only (car
,page
,attr
,count
)
1639 Bit8u car
;Bit8u page
;Bit8u attr
;Bit16u count
;
1641 Bit8u cheight
,xcurs
,ycurs
,mode
,line
,bpp
;
1642 Bit16u nbcols
,nbrows
,address
;
1643 Bit16u cursor
,dummy
;
1646 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1647 line
=find_vga_entry(mode
);
1648 if(line
==0xFF)return;
1650 // Get the cursor pos for the page
1651 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1652 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1654 // Get the dimensions
1655 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1656 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1658 if(vga_modes
[line
].class==TEXT
)
1660 // Compute the address
1661 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
)+(xcurs
+ycurs
*nbcols
)*2;
1664 {write_byte(vga_modes
[line
].sstart
,address
,car
);
1670 // FIXME gfx mode not complete
1671 cheight
=video_param_table
[line_to_vpti
[line
]].cheight
;
1672 bpp
=vga_modes
[line
].pixbits
;
1673 while((count
-->0) && (xcurs
<nbcols
))
1675 switch(vga_modes
[line
].memmodel
)
1679 write_gfx_char_pl4(car
,attr
,xcurs
,ycurs
,nbcols
,cheight
);
1682 write_gfx_char_cga(car
,attr
,xcurs
,ycurs
,nbcols
,bpp
);
1685 write_gfx_char_lin(car
,attr
,xcurs
,ycurs
,nbcols
);
1697 // --------------------------------------------------------------------------------------------
1701 je biosfn_set_border_color
1703 je biosfn_set_palette
1708 biosfn_set_border_color
:
1713 mov dx
, # VGAREG_ACTL_RESET
1715 mov dx
, # VGAREG_ACTL_ADDRESS
1728 mov dx
, # VGAREG_ACTL_ADDRESS
1731 mov dx
, # VGAREG_ACTL_READ_DATA
1735 mov dx
, # VGAREG_ACTL_ADDRESS
1739 jne set_intensity_loop
1752 mov dx
, # VGAREG_ACTL_RESET
1756 set_cga_palette_loop
:
1757 mov dx
, # VGAREG_ACTL_ADDRESS
1760 mov dx
, # VGAREG_ACTL_READ_DATA
1764 mov dx
, # VGAREG_ACTL_ADDRESS
1768 jne set_cga_palette_loop
1778 // --------------------------------------------------------------------------------------------
1779 static void biosfn_write_pixel (BH
,AL
,CX
,DX
) Bit8u BH
;Bit8u AL
;Bit16u CX
;Bit16u DX
;
1781 Bit8u mode
,line
,mask
,attr
,data
;
1785 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1786 line
=find_vga_entry(mode
);
1787 if(line
==0xFF)return;
1788 if(vga_modes
[line
].class==TEXT
)return;
1790 switch(vga_modes
[line
].memmodel
)
1794 addr
= CX
/8+DX
*read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1795 mask
= 0x80 >> (CX
& 0x07);
1796 outw(VGAREG_GRDC_ADDRESS
, (mask
<< 8) | 0x08);
1797 outw(VGAREG_GRDC_ADDRESS
, 0x0205);
1798 data
= read_byte(0xa000,addr
);
1801 outw(VGAREG_GRDC_ADDRESS
, 0x1803);
1803 write_byte(0xa000,addr
,AL
);
1805 mov dx
, # VGAREG_GRDC_ADDRESS
1815 if(vga_modes
[line
].pixbits
==2)
1817 addr
=(CX
>>2)+(DX
>>1)*80;
1821 addr
=(CX
>>3)+(DX
>>1)*80;
1823 if (DX
& 1) addr
+= 0x2000;
1824 data
= read_byte(0xb800,addr
);
1825 if(vga_modes
[line
].pixbits
==2)
1827 attr
= (AL
& 0x03) << ((3 - (CX
& 0x03)) * 2);
1828 mask
= 0x03 << ((3 - (CX
& 0x03)) * 2);
1832 attr
= (AL
& 0x01) << (7 - (CX
& 0x07));
1833 mask
= 0x01 << (7 - (CX
& 0x07));
1844 write_byte(0xb800,addr
,data
);
1847 addr
=CX
+DX
*(read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
)*8);
1848 write_byte(0xa000,addr
,AL
);
1857 // --------------------------------------------------------------------------------------------
1858 static void biosfn_read_pixel (BH
,CX
,DX
,AX
) Bit8u BH
;Bit16u CX
;Bit16u DX
;Bit16u
*AX
;
1860 Bit8u mode
,line
,mask
,attr
,data
,i
;
1865 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1866 line
=find_vga_entry(mode
);
1867 if(line
==0xFF)return;
1868 if(vga_modes
[line
].class==TEXT
)return;
1870 switch(vga_modes
[line
].memmodel
)
1874 addr
= CX
/8+DX
*read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1875 mask
= 0x80 >> (CX
& 0x07);
1879 outw(VGAREG_GRDC_ADDRESS
, (i
<< 8) | 0x04);
1880 data
= read_byte(0xa000,addr
) & mask
;
1881 if (data
> 0) attr
|= (0x01 << i
);
1885 addr
=(CX
>>2)+(DX
>>1)*80;
1886 if (DX
& 1) addr
+= 0x2000;
1887 data
= read_byte(0xb800,addr
);
1888 if(vga_modes
[line
].pixbits
==2)
1890 attr
= (data
>> ((3 - (CX
& 0x03)) * 2)) & 0x03;
1894 attr
= (data
>> (7 - (CX
& 0x07))) & 0x01;
1898 addr
=CX
+DX
*(read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
)*8);
1899 attr
=read_byte(0xa000,addr
);
1907 write_word(ss
,AX
,(read_word(ss
,AX
) & 0xff00) | attr
);
1910 // --------------------------------------------------------------------------------------------
1911 static void biosfn_write_teletype (car
, page
, attr
, flag
)
1912 Bit8u car
;Bit8u page
;Bit8u attr
;Bit8u flag
;
1913 {// flag = WITH_ATTR / NO_ATTR
1915 Bit8u cheight
,xcurs
,ycurs
,mode
,line
,bpp
;
1916 Bit16u nbcols
,nbrows
,address
;
1917 Bit16u cursor
,dummy
;
1919 // special case if page is 0xff, use current page
1921 page
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
);
1924 mode
=read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
);
1925 line
=find_vga_entry(mode
);
1926 if(line
==0xFF)return;
1928 // Get the cursor pos for the page
1929 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1930 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1932 // Get the dimensions
1933 nbrows
=read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)+1;
1934 nbcols
=read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
1957 biosfn_write_teletype(' ',page
,attr
,flag
);
1958 biosfn_get_cursor_pos(page
,&dummy
,&cursor
);
1959 xcurs
=cursor
&0x00ff;ycurs
=(cursor
&0xff00)>>8;
1965 if(vga_modes
[line
].class==TEXT
)
1967 // Compute the address
1968 address
=SCREEN_MEM_START(nbcols
,nbrows
,page
)+(xcurs
+ycurs
*nbcols
)*2;
1971 write_byte(vga_modes
[line
].sstart
,address
,car
);
1974 write_byte(vga_modes
[line
].sstart
,address
+1,attr
);
1978 // FIXME gfx mode not complete
1979 cheight
=video_param_table
[line_to_vpti
[line
]].cheight
;
1980 bpp
=vga_modes
[line
].pixbits
;
1981 switch(vga_modes
[line
].memmodel
)
1985 write_gfx_char_pl4(car
,attr
,xcurs
,ycurs
,nbcols
,cheight
);
1988 write_gfx_char_cga(car
,attr
,xcurs
,ycurs
,nbcols
,bpp
);
1991 write_gfx_char_lin(car
,attr
,xcurs
,ycurs
,nbcols
);
2002 // Do we need to wrap ?
2008 // Do we need to scroll ?
2011 if(vga_modes
[line
].class==TEXT
)
2013 biosfn_scroll(0x01,0x07,0,0,nbrows
-1,nbcols
-1,page
,SCROLL_UP
);
2017 biosfn_scroll(0x01,0x00,0,0,nbrows
-1,nbcols
-1,page
,SCROLL_UP
);
2022 // Set the cursor for the page
2023 cursor
=ycurs
; cursor
<<=8; cursor
+=xcurs
;
2024 biosfn_set_cursor_pos(page
,cursor
);
2027 // --------------------------------------------------------------------------------------------
2029 biosfn_get_video_mode
:
2031 mov ax
, # BIOSMEM_SEG
2034 mov bx
, # BIOSMEM_CURRENT_PAGE
2039 mov bx
, # BIOSMEM_VIDEO_CTL
2042 mov bx
, # BIOSMEM_CURRENT_MODE
2045 mov bx
, # BIOSMEM_NB_COLS
2052 // --------------------------------------------------------------------------------------------
2057 jmp biosfn_set_single_palette_reg
2061 jmp biosfn_set_overscan_border_color
2065 jmp biosfn_set_all_palette_reg
2069 jmp biosfn_toggle_intensity
2073 jmp biosfn_get_single_palette_reg
2077 jmp biosfn_read_overscan_border_color
2081 jmp biosfn_get_all_palette_reg
2085 jmp biosfn_set_single_dac_reg
2089 jmp biosfn_set_all_dac_reg
2093 jmp biosfn_select_video_dac_color_page
2097 jmp biosfn_read_single_dac_reg
2101 jmp biosfn_read_all_dac_reg
2105 jmp biosfn_set_pel_mask
2109 jmp biosfn_read_pel_mask
2112 jne int10_group_10_unknown
2113 jmp biosfn_read_video_dac_state
2114 int10_group_10_unknown
:
2120 biosfn_set_single_palette_reg
:
2125 mov dx
, # VGAREG_ACTL_RESET
2127 mov dx
, # VGAREG_ACTL_ADDRESS
2140 // --------------------------------------------------------------------------------------------
2142 biosfn_set_overscan_border_color
:
2145 call biosfn_set_single_palette_reg
2150 // --------------------------------------------------------------------------------------------
2152 biosfn_set_all_palette_reg
:
2158 mov dx
, # VGAREG_ACTL_RESET
2161 mov dx
, # VGAREG_ACTL_ADDRESS
2171 jne set_palette_loop
2186 // --------------------------------------------------------------------------------------------
2188 biosfn_toggle_intensity
:
2192 mov dx
, # VGAREG_ACTL_RESET
2194 mov dx
, # VGAREG_ACTL_ADDRESS
2197 mov dx
, # VGAREG_ACTL_READ_DATA
2203 mov dx
, # VGAREG_ACTL_ADDRESS
2213 // --------------------------------------------------------------------------------------------
2215 biosfn_get_single_palette_reg
:
2220 mov dx
, # VGAREG_ACTL_RESET
2222 mov dx
, # VGAREG_ACTL_ADDRESS
2225 mov dx
, # VGAREG_ACTL_READ_DATA
2228 mov dx
, # VGAREG_ACTL_RESET
2230 mov dx
, # VGAREG_ACTL_ADDRESS
2239 // --------------------------------------------------------------------------------------------
2241 biosfn_read_overscan_border_color
:
2245 call biosfn_get_single_palette_reg
2253 // --------------------------------------------------------------------------------------------
2255 biosfn_get_all_palette_reg
:
2263 mov dx
, # VGAREG_ACTL_RESET
2265 mov dx
, # VGAREG_ACTL_ADDRESS
2268 mov dx
, # VGAREG_ACTL_READ_DATA
2275 jne get_palette_loop
2276 mov dx
, # VGAREG_ACTL_RESET
2278 mov dx
, # VGAREG_ACTL_ADDRESS
2281 mov dx
, # VGAREG_ACTL_READ_DATA
2285 mov dx
, # VGAREG_ACTL_RESET
2287 mov dx
, # VGAREG_ACTL_ADDRESS
2297 // --------------------------------------------------------------------------------------------
2299 biosfn_set_single_dac_reg
:
2302 mov dx
, # VGAREG_DAC_WRITE_ADDRESS
2305 mov dx
, # VGAREG_DAC_DATA
2319 // --------------------------------------------------------------------------------------------
2321 biosfn_set_all_dac_reg
:
2326 mov dx
, # VGAREG_DAC_WRITE_ADDRESS
2332 mov dx
, # VGAREG_DAC_DATA
2355 // --------------------------------------------------------------------------------------------
2357 biosfn_select_video_dac_color_page
:
2361 mov dx
, # VGAREG_ACTL_RESET
2363 mov dx
, # VGAREG_ACTL_ADDRESS
2366 mov dx
, # VGAREG_ACTL_READ_DATA
2373 mov dx
, # VGAREG_ACTL_ADDRESS
2378 mov dx
, # VGAREG_ACTL_RESET
2380 mov dx
, # VGAREG_ACTL_ADDRESS
2400 // --------------------------------------------------------------------------------------------
2402 biosfn_read_single_dac_reg
:
2405 mov dx
, # VGAREG_DAC_READ_ADDRESS
2410 mov dx
, # VGAREG_DAC_DATA
2423 // --------------------------------------------------------------------------------------------
2425 biosfn_read_all_dac_reg
:
2430 mov dx
, # VGAREG_DAC_READ_ADDRESS
2436 mov dx
, # VGAREG_DAC_DATA
2459 // --------------------------------------------------------------------------------------------
2461 biosfn_set_pel_mask
:
2464 mov dx
, # VGAREG_PEL_MASK
2472 // --------------------------------------------------------------------------------------------
2474 biosfn_read_pel_mask
:
2477 mov dx
, # VGAREG_PEL_MASK
2485 // --------------------------------------------------------------------------------------------
2487 biosfn_read_video_dac_state
:
2490 mov dx
, # VGAREG_ACTL_RESET
2492 mov dx
, # VGAREG_ACTL_ADDRESS
2495 mov dx
, # VGAREG_ACTL_READ_DATA
2499 mov dx
, # VGAREG_ACTL_RESET
2501 mov dx
, # VGAREG_ACTL_ADDRESS
2504 mov dx
, # VGAREG_ACTL_READ_DATA
2512 mov dx
, # VGAREG_ACTL_RESET
2514 mov dx
, # VGAREG_ACTL_ADDRESS
2522 // --------------------------------------------------------------------------------------------
2523 static void biosfn_perform_gray_scale_summing (start
,count
)
2524 Bit16u start
;Bit16u count
;
2529 inb(VGAREG_ACTL_RESET
);
2530 outb(VGAREG_ACTL_ADDRESS
,0x00);
2532 for( index
= 0; index
< count
; index
++ )
2534 // set read address and switch to read mode
2535 outb(VGAREG_DAC_READ_ADDRESS
,start
);
2536 // get 6-bit wide RGB data values
2537 r
=inb( VGAREG_DAC_DATA
);
2538 g
=inb( VGAREG_DAC_DATA
);
2539 b
=inb( VGAREG_DAC_DATA
);
2541 // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
2542 i
= ( ( 77*r
+ 151*g
+ 28*b
) + 0x80 ) >> 8;
2546 // set write address and switch to write mode
2547 outb(VGAREG_DAC_WRITE_ADDRESS
,start
);
2548 // write new intensity value
2549 outb( VGAREG_DAC_DATA
, i
&0xff );
2550 outb( VGAREG_DAC_DATA
, i
&0xff );
2551 outb( VGAREG_DAC_DATA
, i
&0xff );
2554 inb(VGAREG_ACTL_RESET
);
2555 outb(VGAREG_ACTL_ADDRESS
,0x20);
2558 // --------------------------------------------------------------------------------------------
2559 static void get_font_access()
2562 mov dx
, # VGAREG_SEQU_ADDRESS
2571 mov dx
, # VGAREG_GRDC_ADDRESS
2581 static void release_font_access()
2584 mov dx
, # VGAREG_SEQU_ADDRESS
2593 mov dx
, # VGAREG_READ_MISC_OUTPUT
2600 mov dx
, # VGAREG_GRDC_ADDRESS
2616 static void set_scan_lines(lines
) Bit8u lines
;
2618 Bit16u crtc_addr
,cols
,page
,vde
;
2619 Bit8u crtc_r9
,ovl
,rows
;
2621 crtc_addr
= read_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
);
2622 outb(crtc_addr
, 0x09);
2623 crtc_r9
= inb(crtc_addr
+1);
2624 crtc_r9
= (crtc_r9
& 0xe0) | (lines
- 1);
2625 outb(crtc_addr
+1, crtc_r9
);
2628 biosfn_set_cursor_shape(0x06,0x07);
2632 biosfn_set_cursor_shape(lines
-4,lines
-3);
2634 write_word(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
, lines
);
2635 outb(crtc_addr
, 0x12);
2636 vde
= inb(crtc_addr
+1);
2637 outb(crtc_addr
, 0x07);
2638 ovl
= inb(crtc_addr
+1);
2639 vde
+= (((ovl
& 0x02) << 7) + ((ovl
& 0x40) << 3) + 1);
2641 write_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
, rows
-1);
2642 cols
= read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
);
2643 write_word(BIOSMEM_SEG
,BIOSMEM_PAGE_SIZE
, rows
* cols
* 2);
2646 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
;
2648 Bit16u blockaddr
,dest
,i
,src
;
2651 blockaddr
= ((BL
& 0x03) << 14) + ((BL
& 0x04) << 11);
2655 dest
= blockaddr
+ (DX
+ i
) * 32;
2656 memcpyb(0xA000, dest
, ES
, src
, BH
);
2658 release_font_access();
2665 static void biosfn_load_text_8_14_pat (AL
,BL
) Bit8u AL
;Bit8u BL
;
2667 Bit16u blockaddr
,dest
,i
,src
;
2670 blockaddr
= ((BL
& 0x03) << 14) + ((BL
& 0x04) << 11);
2671 for(i
=0;i
<0x100;i
++)
2674 dest
= blockaddr
+ i
* 32;
2675 memcpyb(0xA000, dest
, 0xC000, vgafont14
+src
, 14);
2677 release_font_access();
2684 static void biosfn_load_text_8_8_pat (AL
,BL
) Bit8u AL
;Bit8u BL
;
2686 Bit16u blockaddr
,dest
,i
,src
;
2689 blockaddr
= ((BL
& 0x03) << 14) + ((BL
& 0x04) << 11);
2690 for(i
=0;i
<0x100;i
++)
2693 dest
= blockaddr
+ i
* 32;
2694 memcpyb(0xA000, dest
, 0xC000, vgafont8
+src
, 8);
2696 release_font_access();
2703 // --------------------------------------------------------------------------------------------
2705 biosfn_set_text_block_specifier
:
2708 mov dx
, # VGAREG_SEQU_ADDRESS
2717 // --------------------------------------------------------------------------------------------
2718 static void biosfn_load_text_8_16_pat (AL
,BL
) Bit8u AL
;Bit8u BL
;
2720 Bit16u blockaddr
,dest
,i
,src
;
2723 blockaddr
= ((BL
& 0x03) << 14) + ((BL
& 0x04) << 11);
2724 for(i
=0;i
<0x100;i
++)
2727 dest
= blockaddr
+ i
* 32;
2728 memcpyb(0xA000, dest
, 0xC000, vgafont16
+src
, 16);
2730 release_font_access();
2737 static void biosfn_load_gfx_8_8_chars (ES
,BP
) Bit16u ES
;Bit16u BP
;
2743 static void biosfn_load_gfx_user_chars (ES
,BP
,CX
,BL
,DL
) Bit16u ES
;Bit16u BP
;Bit16u CX
;Bit8u BL
;Bit8u DL
;
2749 static void biosfn_load_gfx_8_14_chars (BL
) Bit8u BL
;
2755 static void biosfn_load_gfx_8_8_dd_chars (BL
) Bit8u BL
;
2761 static void biosfn_load_gfx_8_16_chars (BL
) Bit8u BL
;
2767 // --------------------------------------------------------------------------------------------
2768 static void biosfn_get_font_info (BH
,ES
,BP
,CX
,DX
)
2769 Bit8u BH
;Bit16u
*ES
;Bit16u
*BP
;Bit16u
*CX
;Bit16u
*DX
;
2770 {Bit16u ss
=get_SS();
2774 write_word(ss
,ES
,read_word(0x00,0x1f*4));
2775 write_word(ss
,BP
,read_word(0x00,(0x1f*4)+2));
2778 write_word(ss
,ES
,read_word(0x00,0x43*4));
2779 write_word(ss
,BP
,read_word(0x00,(0x43*4)+2));
2782 write_word(ss
,ES
,0xC000);
2783 write_word(ss
,BP
,vgafont14
);
2786 write_word(ss
,ES
,0xC000);
2787 write_word(ss
,BP
,vgafont8
);
2790 write_word(ss
,ES
,0xC000);
2791 write_word(ss
,BP
,vgafont8
+128*8);
2794 write_word(ss
,ES
,0xC000);
2795 write_word(ss
,BP
,vgafont14alt
);
2798 write_word(ss
,ES
,0xC000);
2799 write_word(ss
,BP
,vgafont16
);
2802 write_word(ss
,ES
,0xC000);
2803 write_word(ss
,BP
,vgafont16alt
);
2807 printf("Get font info BH(%02x) was discarded\n",BH
);
2811 // Set byte/char of on screen font
2812 write_word(ss
,CX
,(Bit16u
)read_byte(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
));
2814 // Set Highest char row
2815 write_word(ss
,DX
,(Bit16u
)read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
));
2818 // --------------------------------------------------------------------------------------------
2820 biosfn_get_ega_info
:
2823 mov ax
, # BIOSMEM_SEG
2826 mov bx
, # BIOSMEM_SWITCHES
2829 mov bx
, # BIOSMEM_CRTC_ADDRESS
2832 cmp ax
, # VGAREG_MDA_CRTC_ADDRESS
2841 // --------------------------------------------------------------------------------------------
2842 static void biosfn_alternate_prtsc()
2849 // --------------------------------------------------------------------------------------------
2851 biosfn_select_vert_res
:
2853 ; res
: 00 200 lines
, 01 350 lines
, 02 400 lines
2859 mov ax
, # BIOSMEM_SEG
2861 mov bx
, # BIOSMEM_MODESET_CTL
2863 mov bx
, # BIOSMEM_SWITCHES
2874 mov bx
, #msg_vert_res
2882 ; reset modeset ctl bit
7 and set bit
4
2883 ; set switches bit
3-0 to
0x09
2892 ; reset modeset ctl bit
7 and bit
4
2893 ; set switches bit
3-0 to
0x09
2901 ; set modeset ctl bit
7 and reset bit
4
2902 ; set switches bit
3-0 to
0x08
2909 mov bx
, # BIOSMEM_MODESET_CTL
2911 mov bx
, # BIOSMEM_SWITCHES
2922 .ascii
"Select vert res (%02x) was discarded"
2923 .byte
0x0d,0x0a,0x00
2927 biosfn_enable_default_palette_loading
:
2934 mov ax
, # BIOSMEM_SEG
2936 mov bx
, # BIOSMEM_MODESET_CTL
2948 biosfn_enable_video_addressing
:
2955 mov dx
, # VGAREG_READ_MISC_OUTPUT
2959 mov dx
, # VGAREG_WRITE_MISC_OUTPUT
2967 biosfn_enable_grayscale_summing
:
2975 mov ax
, # BIOSMEM_SEG
2977 mov bx
, # BIOSMEM_MODESET_CTL
2989 biosfn_enable_cursor_emulation
:
2996 mov ax
, # BIOSMEM_SEG
2998 mov bx
, # BIOSMEM_MODESET_CTL
3010 // --------------------------------------------------------------------------------------------
3011 static void biosfn_switch_video_interface (AL
,ES
,DX
) Bit8u AL
;Bit16u ES
;Bit16u DX
;
3017 static void biosfn_enable_video_refresh_control (AL
) Bit8u AL
;
3024 // --------------------------------------------------------------------------------------------
3025 static void biosfn_write_string (flag
,page
,attr
,count
,row
,col
,seg
,offset
)
3026 Bit8u flag
;Bit8u page
;Bit8u attr
;Bit16u count
;Bit8u row
;Bit8u col
;Bit16u seg
;Bit16u offset
;
3028 Bit16u newcurs
,oldcurs
,dummy
;
3031 // Read curs info for the page
3032 biosfn_get_cursor_pos(page
,&dummy
,&oldcurs
);
3034 // if row=0xff special case : use current cursor position
3036 {col
=oldcurs
&0x00ff;
3037 row
=(oldcurs
&0xff00)>>8;
3040 newcurs
=row
; newcurs
<<=8; newcurs
+=col
;
3041 biosfn_set_cursor_pos(page
,newcurs
);
3045 car
=read_byte(seg
,offset
++);
3047 attr
=read_byte(seg
,offset
++);
3049 biosfn_write_teletype(car
,page
,attr
,WITH_ATTR
);
3052 // Set back curs pos
3054 biosfn_set_cursor_pos(page
,oldcurs
);
3057 // --------------------------------------------------------------------------------------------
3061 je biosfn_read_display_code
3063 je biosfn_set_display_code
3068 biosfn_read_display_code
:
3071 mov ax
, # BIOSMEM_SEG
3073 mov bx
, # BIOSMEM_DCC_INDEX
3081 biosfn_set_display_code
:
3085 mov ax
, # BIOSMEM_SEG
3088 mov bx
, # BIOSMEM_DCC_INDEX
3094 mov bx
, #msg_alt_dcc
3107 .ascii
"Alternate Display code (%02x) was discarded"
3108 .byte
0x0d,0x0a,0x00
3112 // --------------------------------------------------------------------------------------------
3113 static void biosfn_read_state_info (BX
,ES
,DI
)
3114 Bit16u BX
;Bit16u ES
;Bit16u DI
;
3116 // Address of static functionality table
3117 write_word(ES
,DI
+0x00,&static_functionality
);
3118 write_word(ES
,DI
+0x02,0xC000);
3120 // Hard coded copy from BIOS area. Should it be cleaner ?
3121 memcpyb(ES
,DI
+0x04,BIOSMEM_SEG
,0x49,30);
3122 memcpyb(ES
,DI
+0x22,BIOSMEM_SEG
,0x84,3);
3124 write_byte(ES
,DI
+0x25,read_byte(BIOSMEM_SEG
,BIOSMEM_DCC_INDEX
));
3125 write_byte(ES
,DI
+0x26,0);
3126 write_byte(ES
,DI
+0x27,16);
3127 write_byte(ES
,DI
+0x28,0);
3128 write_byte(ES
,DI
+0x29,8);
3129 write_byte(ES
,DI
+0x2a,2);
3130 write_byte(ES
,DI
+0x2b,0);
3131 write_byte(ES
,DI
+0x2c,0);
3132 write_byte(ES
,DI
+0x31,3);
3133 write_byte(ES
,DI
+0x32,0);
3135 memsetb(ES
,DI
+0x33,0,13);
3138 // --------------------------------------------------------------------------------------------
3139 // --------------------------------------------------------------------------------------------
3140 static Bit16u
biosfn_read_video_state_size2 (CX
)
3149 size
+= (5 + 8 + 5) * 2 + 6;
3152 size
+= 3 + 256 * 3 + 1;
3157 static void biosfn_read_video_state_size (CX
, BX
)
3158 Bit16u CX
; Bit16u
*BX
;
3161 write_word(ss
, BX
, biosfn_read_video_state_size2(CX
));
3164 static Bit16u
biosfn_save_video_state (CX
,ES
,BX
)
3165 Bit16u CX
;Bit16u ES
;Bit16u BX
;
3167 Bit16u i
, v
, crtc_addr
, ar_index
;
3169 crtc_addr
= read_word(BIOSMEM_SEG
, BIOSMEM_CRTC_ADDRESS
);
3171 write_byte(ES
, BX
, inb(VGAREG_SEQU_ADDRESS
)); BX
++;
3172 write_byte(ES
, BX
, inb(crtc_addr
)); BX
++;
3173 write_byte(ES
, BX
, inb(VGAREG_GRDC_ADDRESS
)); BX
++;
3174 inb(VGAREG_ACTL_RESET
);
3175 ar_index
= inb(VGAREG_ACTL_ADDRESS
);
3176 write_byte(ES
, BX
, ar_index
); BX
++;
3177 write_byte(ES
, BX
, inb(VGAREG_READ_FEATURE_CTL
)); BX
++;
3180 outb(VGAREG_SEQU_ADDRESS
, i
);
3181 write_byte(ES
, BX
, inb(VGAREG_SEQU_DATA
)); BX
++;
3183 outb(VGAREG_SEQU_ADDRESS
, 0);
3184 write_byte(ES
, BX
, inb(VGAREG_SEQU_DATA
)); BX
++;
3186 for(i
=0;i
<=0x18;i
++) {
3188 write_byte(ES
, BX
, inb(crtc_addr
+1)); BX
++;
3191 for(i
=0;i
<=0x13;i
++) {
3192 inb(VGAREG_ACTL_RESET
);
3193 outb(VGAREG_ACTL_ADDRESS
, i
| (ar_index
& 0x20));
3194 write_byte(ES
, BX
, inb(VGAREG_ACTL_READ_DATA
)); BX
++;
3196 inb(VGAREG_ACTL_RESET
);
3199 outb(VGAREG_GRDC_ADDRESS
,i
);
3200 write_byte(ES
, BX
, inb(VGAREG_GRDC_DATA
)); BX
++;
3203 write_word(ES
, BX
, crtc_addr
); BX
+= 2;
3205 /* XXX: read plane latches */
3206 write_byte(ES
, BX
, 0); BX
++;
3207 write_byte(ES
, BX
, 0); BX
++;
3208 write_byte(ES
, BX
, 0); BX
++;
3209 write_byte(ES
, BX
, 0); BX
++;
3212 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
)); BX
++;
3213 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
)); BX
+= 2;
3214 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_PAGE_SIZE
)); BX
+= 2;
3215 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
)); BX
+= 2;
3216 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
)); BX
++;
3217 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
)); BX
+= 2;
3218 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_VIDEO_CTL
)); BX
++;
3219 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_SWITCHES
)); BX
++;
3220 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
)); BX
++;
3221 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_CURSOR_TYPE
)); BX
+= 2;
3223 write_word(ES
, BX
, read_word(BIOSMEM_SEG
, BIOSMEM_CURSOR_POS
+2*i
));
3226 write_word(ES
, BX
, read_word(BIOSMEM_SEG
,BIOSMEM_CURRENT_START
)); BX
+= 2;
3227 write_byte(ES
, BX
, read_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
)); BX
++;
3229 write_word(ES
, BX
, read_word(0, 0x1f * 4)); BX
+= 2;
3230 write_word(ES
, BX
, read_word(0, 0x1f * 4 + 2)); BX
+= 2;
3231 write_word(ES
, BX
, read_word(0, 0x43 * 4)); BX
+= 2;
3232 write_word(ES
, BX
, read_word(0, 0x43 * 4 + 2)); BX
+= 2;
3235 /* XXX: check this */
3236 write_byte(ES
, BX
, inb(VGAREG_DAC_STATE
)); BX
++; /* read/write mode dac */
3237 write_byte(ES
, BX
, inb(VGAREG_DAC_WRITE_ADDRESS
)); BX
++; /* pix address */
3238 write_byte(ES
, BX
, inb(VGAREG_PEL_MASK
)); BX
++;
3239 // Set the whole dac always, from 0
3240 outb(VGAREG_DAC_WRITE_ADDRESS
,0x00);
3241 for(i
=0;i
<256*3;i
++) {
3242 write_byte(ES
, BX
, inb(VGAREG_DAC_DATA
)); BX
++;
3244 write_byte(ES
, BX
, 0); BX
++; /* color select register */
3249 static Bit16u
biosfn_restore_video_state (CX
,ES
,BX
)
3250 Bit16u CX
;Bit16u ES
;Bit16u BX
;
3252 Bit16u i
, crtc_addr
, v
, addr1
, ar_index
;
3255 // Reset Attribute Ctl flip-flop
3256 inb(VGAREG_ACTL_RESET
);
3258 crtc_addr
= read_word(ES
, BX
+ 0x40);
3263 outb(VGAREG_SEQU_ADDRESS
, i
);
3264 outb(VGAREG_SEQU_DATA
, read_byte(ES
, BX
)); BX
++;
3266 outb(VGAREG_SEQU_ADDRESS
, 0);
3267 outb(VGAREG_SEQU_DATA
, read_byte(ES
, BX
)); BX
++;
3269 // Disable CRTC write protection
3270 outw(crtc_addr
,0x0011);
3272 for(i
=0;i
<=0x18;i
++) {
3275 outb(crtc_addr
+1, read_byte(ES
, BX
));
3279 // select crtc base address
3280 v
= inb(VGAREG_READ_MISC_OUTPUT
) & ~0x01;
3281 if (crtc_addr
= 0x3d4)
3283 outb(VGAREG_WRITE_MISC_OUTPUT
, v
);
3285 // enable write protection if needed
3286 outb(crtc_addr
, 0x11);
3287 outb(crtc_addr
+1, read_byte(ES
, BX
- 0x18 + 0x11));
3289 // Set Attribute Ctl
3290 ar_index
= read_byte(ES
, addr1
+ 0x03);
3291 inb(VGAREG_ACTL_RESET
);
3292 for(i
=0;i
<=0x13;i
++) {
3293 outb(VGAREG_ACTL_ADDRESS
, i
| (ar_index
& 0x20));
3294 outb(VGAREG_ACTL_WRITE_DATA
, read_byte(ES
, BX
)); BX
++;
3296 outb(VGAREG_ACTL_ADDRESS
, ar_index
);
3297 inb(VGAREG_ACTL_RESET
);
3300 outb(VGAREG_GRDC_ADDRESS
,i
);
3301 outb(VGAREG_GRDC_DATA
, read_byte(ES
, BX
)); BX
++;
3303 BX
+= 2; /* crtc_addr */
3304 BX
+= 4; /* plane latches */
3306 outb(VGAREG_SEQU_ADDRESS
, read_byte(ES
, addr1
)); addr1
++;
3307 outb(crtc_addr
, read_byte(ES
, addr1
)); addr1
++;
3308 outb(VGAREG_GRDC_ADDRESS
, read_byte(ES
, addr1
)); addr1
++;
3310 outb(crtc_addr
- 0x4 + 0xa, read_byte(ES
, addr1
)); addr1
++;
3313 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_MODE
, read_byte(ES
, BX
)); BX
++;
3314 write_word(BIOSMEM_SEG
,BIOSMEM_NB_COLS
, read_word(ES
, BX
)); BX
+= 2;
3315 write_word(BIOSMEM_SEG
,BIOSMEM_PAGE_SIZE
, read_word(ES
, BX
)); BX
+= 2;
3316 write_word(BIOSMEM_SEG
,BIOSMEM_CRTC_ADDRESS
, read_word(ES
, BX
)); BX
+= 2;
3317 write_byte(BIOSMEM_SEG
,BIOSMEM_NB_ROWS
, read_byte(ES
, BX
)); BX
++;
3318 write_word(BIOSMEM_SEG
,BIOSMEM_CHAR_HEIGHT
, read_word(ES
, BX
)); BX
+= 2;
3319 write_byte(BIOSMEM_SEG
,BIOSMEM_VIDEO_CTL
, read_byte(ES
, BX
)); BX
++;
3320 write_byte(BIOSMEM_SEG
,BIOSMEM_SWITCHES
, read_byte(ES
, BX
)); BX
++;
3321 write_byte(BIOSMEM_SEG
,BIOSMEM_MODESET_CTL
, read_byte(ES
, BX
)); BX
++;
3322 write_word(BIOSMEM_SEG
,BIOSMEM_CURSOR_TYPE
, read_word(ES
, BX
)); BX
+= 2;
3324 write_word(BIOSMEM_SEG
, BIOSMEM_CURSOR_POS
+2*i
, read_word(ES
, BX
));
3327 write_word(BIOSMEM_SEG
,BIOSMEM_CURRENT_START
, read_word(ES
, BX
)); BX
+= 2;
3328 write_byte(BIOSMEM_SEG
,BIOSMEM_CURRENT_PAGE
, read_byte(ES
, BX
)); BX
++;
3330 write_word(0, 0x1f * 4, read_word(ES
, BX
)); BX
+= 2;
3331 write_word(0, 0x1f * 4 + 2, read_word(ES
, BX
)); BX
+= 2;
3332 write_word(0, 0x43 * 4, read_word(ES
, BX
)); BX
+= 2;
3333 write_word(0, 0x43 * 4 + 2, read_word(ES
, BX
)); BX
+= 2;
3337 v
= read_byte(ES
, BX
); BX
++;
3338 outb(VGAREG_PEL_MASK
, read_byte(ES
, BX
)); BX
++;
3339 // Set the whole dac always, from 0
3340 outb(VGAREG_DAC_WRITE_ADDRESS
,0x00);
3341 for(i
=0;i
<256*3;i
++) {
3342 outb(VGAREG_DAC_DATA
, read_byte(ES
, BX
)); BX
++;
3345 outb(VGAREG_DAC_WRITE_ADDRESS
, v
);
3350 // ============================================================================================
3354 // ============================================================================================
3356 // --------------------------------------------------------------------------------------------
3357 static Bit8u
find_vga_entry(mode
)
3361 for(i
=0;i
<=MODE_MAX
;i
++)
3362 if(vga_modes
[i
].svgamode
==mode
)
3369 /* =========================================================== */
3373 /* =========================================================== */
3375 // --------------------------------------------------------------------------------------------
3376 static void memsetb(seg
,offset
,value
,count
)
3391 mov cx
, 10[bp
] ; count
3394 mov ax
, 4[bp
] ; segment
3396 mov ax
, 6[bp
] ; offset
3398 mov al
, 8[bp
] ; value
3413 // --------------------------------------------------------------------------------------------
3414 static void memsetw(seg
,offset
,value
,count
)
3429 mov cx
, 10[bp
] ; count
3432 mov ax
, 4[bp
] ; segment
3434 mov ax
, 6[bp
] ; offset
3436 mov ax
, 8[bp
] ; value
3451 // --------------------------------------------------------------------------------------------
3452 static void memcpyb(dseg
,doffset
,sseg
,soffset
,count
)
3470 mov cx
, 12[bp
] ; count
3473 mov ax
, 4[bp
] ; dsegment
3475 mov ax
, 6[bp
] ; doffset
3477 mov ax
, 8[bp
] ; ssegment
3479 mov ax
, 10[bp
] ; soffset
3497 // --------------------------------------------------------------------------------------------
3498 static void memcpyw(dseg
,doffset
,sseg
,soffset
,count
)
3516 mov cx
, 12[bp
] ; count
3519 mov ax
, 4[bp
] ; dsegment
3521 mov ax
, 6[bp
] ; doffset
3523 mov ax
, 8[bp
] ; ssegment
3525 mov ax
, 10[bp
] ; soffset
3543 /* =========================================================== */
3545 * These functions where ripped from Kevin's rombios.c
3547 /* =========================================================== */
3549 // --------------------------------------------------------------------------------------------
3551 read_byte(seg
, offset
)
3561 mov ax
, 4[bp
] ; segment
3563 mov bx
, 6[bp
] ; offset
3565 ;; al
= return value (byte
)
3573 // --------------------------------------------------------------------------------------------
3575 read_word(seg
, offset
)
3585 mov ax
, 4[bp
] ; segment
3587 mov bx
, 6[bp
] ; offset
3589 ;; ax
= return value (word
)
3597 // --------------------------------------------------------------------------------------------
3599 write_byte(seg
, offset
, data
)
3611 mov ax
, 4[bp
] ; segment
3613 mov bx
, 6[bp
] ; offset
3614 mov al
, 8[bp
] ; data byte
3615 mov
[bx
], al
; write data byte
3624 // --------------------------------------------------------------------------------------------
3626 write_word(seg
, offset
, data
)
3638 mov ax
, 4[bp
] ; segment
3640 mov bx
, 6[bp
] ; offset
3641 mov ax
, 8[bp
] ; data word
3642 mov
[bx
], ax
; write data word
3651 // --------------------------------------------------------------------------------------------
3686 // --------------------------------------------------------------------------------------------
3708 // --------------------------------------------------------------------------------------------
3738 void unimplemented()
3740 printf("--> Unimplemented\n");
3745 printf("--> Unknown int10\n");
3749 // --------------------------------------------------------------------------------------------
3750 #if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG)
3754 Bit8u c
, format_char
;
3756 unsigned format_width
, i
;
3758 Bit16u arg_seg
, arg
, digit
, nibble
, shift_count
;
3766 while (c
= read_byte(0xc000, s
)) {
3771 else if (in_format
) {
3772 if ( (c
>='0') && (c
<='9') ) {
3773 format_width
= (format_width
* 10) + (c
- '0');
3775 else if (c
== 'x') {
3776 arg_ptr
++; // increment to next arg
3777 arg
= read_word(arg_seg
, arg_ptr
);
3778 if (format_width
== 0)
3781 digit
= format_width
- 1;
3782 for (i
=0; i
<format_width
; i
++) {
3783 nibble
= (arg
>> (4 * digit
)) & 0x000f;
3785 outb(0x0500, nibble
+ '0');
3787 outb(0x0500, (nibble
- 10) + 'A');
3792 //else if (c == 'd') {
3812 // --------------------------------------------------------------------------------------------
3815 ;; DATA_SEG_DEFS_HERE
3819 .ascii
"vgabios ends here"
3823 ;; BLOCK_STRINGS_BEGIN