1
// ============================================================================================
5
// ============================================================================================
7
// Copyright (C) 2001-2008 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
154
.word vgabios_pci_data
157
// Info from Bart Oldeman
163
.ascii "Plex86/Bochs VGABios"
184
.ascii "(C) 2008 the LGPL VGABios developers Team"
189
.ascii "This VGA/VBE Bios is released under the GNU LGPL"
195
.ascii "Please visit :"
197
;;.ascii " . http://www.plex86.org"
199
.ascii " . http://bochs.sourceforge.net"
201
.ascii " . http://www.nongnu.org/vgabios"
211
.word 0x00b8 // CLGD5446
213
#error "Unknown PCI vendor and device id"
218
.byte 0x0 // class,hi: vga display
219
.word 0x300 // class,lo: vga display
220
.word 0x40 // bios size
222
.byte 0 // intel x86 data
223
.byte 0x80 // last image
228
;; ============================================================================================
232
;; ============================================================================================
238
;; init basic bios vars
242
;; init vbe functions
247
SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler)
253
;; display splash screen
254
call _display_splash_screen
256
;; init video mode and clear the screen
265
call vbe_display_info
270
call cirrus_display_info
280
vgabios_int10_handler:
295
call biosfn_get_video_mode
310
call biosfn_set_text_block_specifier
317
call biosfn_get_ega_info
322
call biosfn_select_vert_res
327
call biosfn_enable_default_palette_loading
332
call biosfn_enable_video_addressing
337
call biosfn_enable_grayscale_summing
342
call biosfn_enable_cursor_emulation
360
jne int10_test_vbe_05
361
call vbe_biosfn_return_current_mode
365
jne int10_test_vbe_06
366
call vbe_biosfn_display_window_control
370
jne int10_test_vbe_07
371
call vbe_biosfn_set_get_logical_scan_line_length
375
jne int10_test_vbe_08
376
call vbe_biosfn_set_get_display_start
380
jne int10_test_vbe_0A
381
call vbe_biosfn_set_get_dac_palette_format
386
call vbe_biosfn_return_protected_mode_interface
395
;; We have to set ds to access the right data segment
408
#include "vgatables.h"
409
#include "vgafonts.h"
412
* Boot time harware inits
416
;; switch to color mode and enable CPU access 480 lines
421
;; more than 64k 3C4/04
429
#if defined(USE_BX_INFO) || defined(DEBUG)
430
mov bx, #msg_vga_init
438
#if defined(USE_BX_INFO) || defined(DEBUG)
440
.ascii "VGABios $Id: vgabios.c,v 1.69 2009/04/07 18:18:20 vruppert Exp $"
445
// --------------------------------------------------------------------------------------------
447
* Boot time bios area inits
452
mov ax, # BIOSMEM_SEG
455
;; init detected hardware BIOS Area
456
mov bx, # BIOSMEM_INITIAL_MODE
459
;; set 80x25 color (not clear from RBIL but usual)
463
;; Just for the first int10 find its children
465
;; the default char height
466
mov bx, # BIOSMEM_CHAR_HEIGHT
471
mov bx, # BIOSMEM_VIDEO_CTL
475
;; Set the basic screen we have
476
mov bx, # BIOSMEM_SWITCHES
480
;; Set the basic modeset options
481
mov bx, # BIOSMEM_MODESET_CTL
485
;; Set the default MSR
486
mov bx, # BIOSMEM_CURRENT_MSR
493
_video_save_pointer_table:
494
.word _video_param_table
497
.word 0 /* XXX: fill it */
500
.word 0 /* XXX: fill it */
503
.word 0 /* XXX: fill it */
506
.word 0 /* XXX: fill it */
509
.word 0 /* XXX: fill it */
512
.word 0 /* XXX: fill it */
517
// --------------------------------------------------------------------------------------------
519
* Boot time Splash screen
521
static void display_splash_screen()
525
// --------------------------------------------------------------------------------------------
530
static void display_info()
537
mov si,#vgabios_version
540
;;mov si,#vgabios_copyright
541
;;call _display_string
543
;;call _display_string
545
mov si,#vgabios_license
547
mov si,#vgabios_website
552
static void display_string()
554
// Get length of string
581
// --------------------------------------------------------------------------------------------
583
static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
584
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
586
// 0E is write char...
588
printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX);
592
// --------------------------------------------------------------------------------------------
594
* int10 main dispatcher
596
static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS)
597
Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS;
604
biosfn_set_video_mode(GET_AL());
605
switch(GET_AL()&0x7F)
623
biosfn_set_cursor_shape(GET_CH(),GET_CL());
626
biosfn_set_cursor_pos(GET_BH(),DX);
629
biosfn_get_cursor_pos(GET_BH(),&CX,&DX);
632
// Read light pen pos (unimplemented)
642
biosfn_set_active_page(GET_AL());
645
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP);
648
biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN);
651
biosfn_read_char_attr(GET_BH(),&AX);
654
biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX);
657
biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX);
660
biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX);
663
biosfn_read_pixel(GET_BH(),CX,DX,&AX);
666
// Ralf Brown Interrupt list is WRONG on bh(page)
667
// We do output only on the current page !
668
biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR);
671
// All other functions of group AH=0x10 rewritten in assembler
672
biosfn_perform_gray_scale_summing(BX,CX);
679
biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH());
683
biosfn_load_text_8_14_pat(GET_AL(),GET_BL());
687
biosfn_load_text_8_8_pat(GET_AL(),GET_BL());
691
biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
694
biosfn_load_gfx_8_8_chars(ES,BP);
697
biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL());
700
biosfn_load_gfx_8_14_chars(GET_BL());
703
biosfn_load_gfx_8_8_dd_chars(GET_BL());
706
biosfn_load_gfx_8_16_chars(GET_BL());
709
biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX);
722
biosfn_alternate_prtsc();
725
biosfn_switch_video_interface(GET_AL(),ES,DX);
729
biosfn_enable_video_refresh_control(GET_AL());
739
biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
742
biosfn_read_state_info(BX,ES,DI);
749
biosfn_read_video_state_size(CX,&BX);
752
biosfn_save_video_state(CX,ES,BX);
755
biosfn_restore_video_state(CX,ES,BX);
767
if (vbe_has_vbe_display()) {
771
vbe_biosfn_return_controller_information(&AX,ES,DI);
774
vbe_biosfn_return_mode_information(&AX,CX,ES,DI);
777
vbe_biosfn_set_mode(&AX,BX,ES,DI);
780
vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX);
820
// ============================================================================================
824
// ============================================================================================
826
static void biosfn_set_video_mode(mode) Bit8u mode;
827
{// mode: Bit 7 is 1 if no clear screen
829
// Should we clear the screen ?
830
Bit8u noclearmem=mode&0x80;
831
Bit8u line,mmask,*palette,vpti;
832
Bit16u i,twidth,theightm1,cheight;
833
Bit8u modeset_ctl,video_ctl,vga_switches;
837
if (vbe_has_vbe_display()) {
838
dispi_set_enable(VBE_DISPI_DISABLED);
845
// find the entry in the video modes
846
line=find_vga_entry(mode);
849
printf("mode search %02x found line %02x\n",mode,line);
855
vpti=line_to_vpti[line];
856
twidth=video_param_table[vpti].twidth;
857
theightm1=video_param_table[vpti].theightm1;
858
cheight=video_param_table[vpti].cheight;
860
// Read the bios vga control
861
video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
863
// Read the bios vga switches
864
vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES);
866
// Read the bios mode set control
867
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
869
// Then we know the number of lines
872
// if palette loading (bit 3 of modeset ctl = 0)
873
if((modeset_ctl&0x08)==0)
875
outb(VGAREG_PEL_MASK,vga_modes[line].pelmask);
877
// Set the whole dac always, from 0
878
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
880
// From which palette
881
switch(vga_modes[line].dacmodel)
895
// Always 256*3 values
896
for(i=0;i<0x0100;i++)
897
{if(i<=dac_regs[vga_modes[line].dacmodel])
898
{outb(VGAREG_DAC_DATA,palette[(i*3)+0]);
899
outb(VGAREG_DAC_DATA,palette[(i*3)+1]);
900
outb(VGAREG_DAC_DATA,palette[(i*3)+2]);
903
{outb(VGAREG_DAC_DATA,0);
904
outb(VGAREG_DAC_DATA,0);
905
outb(VGAREG_DAC_DATA,0);
908
if((modeset_ctl&0x02)==0x02)
910
biosfn_perform_gray_scale_summing(0x00, 0x100);
914
// Reset Attribute Ctl flip-flop
915
inb(VGAREG_ACTL_RESET);
919
{outb(VGAREG_ACTL_ADDRESS,i);
920
outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]);
922
outb(VGAREG_ACTL_ADDRESS,0x14);
923
outb(VGAREG_ACTL_WRITE_DATA,0x00);
926
outb(VGAREG_SEQU_ADDRESS,0);
927
outb(VGAREG_SEQU_DATA,0x03);
929
{outb(VGAREG_SEQU_ADDRESS,i);
930
outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]);
935
{outb(VGAREG_GRDC_ADDRESS,i);
936
outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]);
939
// Set CRTC address VGA or MDA
940
crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS;
942
// Disable CRTC write protection
943
outw(crtc_addr,0x0011);
947
outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]);
950
// Set the misc register
951
outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg);
954
outb(VGAREG_ACTL_ADDRESS,0x20);
955
inb(VGAREG_ACTL_RESET);
959
if(vga_modes[line].class==TEXT)
961
memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k
967
memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k
971
outb( VGAREG_SEQU_ADDRESS, 0x02 );
972
mmask = inb( VGAREG_SEQU_DATA );
973
outb( VGAREG_SEQU_DATA, 0x0f ); // all planes
974
memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k
975
outb( VGAREG_SEQU_DATA, mmask );
981
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode);
982
write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth);
983
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l);
984
write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr);
985
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1);
986
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight);
987
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem));
988
write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9);
989
write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
991
// FIXME We nearly have the good tables. to be reworked
992
write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now
993
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table);
994
write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000);
997
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but...
998
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but...
1001
if(vga_modes[line].class==TEXT)
1003
biosfn_set_cursor_shape(0x06,0x07);
1006
// Set cursor pos for page 0..7
1008
biosfn_set_cursor_pos(i,0x0000);
1010
// Set active page 0
1011
biosfn_set_active_page(0x00);
1013
// Write the fonts in memory
1014
if(vga_modes[line].class==TEXT)
1017
;; copy and activate 8x16 font
1027
// Set the ints 0x1F and 0x43
1029
SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8)
1035
SET_INT_VECTOR(0x43, #0xC000, #_vgafont8)
1040
SET_INT_VECTOR(0x43, #0xC000, #_vgafont14)
1045
SET_INT_VECTOR(0x43, #0xC000, #_vgafont16)
1051
// --------------------------------------------------------------------------------------------
1052
static void biosfn_set_cursor_shape (CH,CL)
1054
{Bit16u cheight,curs,crtc_addr;
1061
write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs);
1063
modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
1064
cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
1065
if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20))
1069
CH = ((CH+1) * cheight / 8) -1;
1073
CH = ((CL+1) * cheight / 8) - 2;
1075
CL = ((CL+1) * cheight / 8) - 1;
1078
// CTRC regs 0x0a and 0x0b
1079
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1080
outb(crtc_addr,0x0a);
1081
outb(crtc_addr+1,CH);
1082
outb(crtc_addr,0x0b);
1083
outb(crtc_addr+1,CL);
1086
// --------------------------------------------------------------------------------------------
1087
static void biosfn_set_cursor_pos (page, cursor)
1088
Bit8u page;Bit16u cursor;
1090
Bit8u xcurs,ycurs,current;
1091
Bit16u nbcols,nbrows,address,crtc_addr;
1093
// Should not happen...
1097
write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor);
1099
// Set the hardware cursor
1100
current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1103
// Get the dimensions
1104
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1105
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1107
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1109
// Calculate the address knowing nbcols nbrows and page num
1110
address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols;
1112
// CRTC regs 0x0e and 0x0f
1113
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1114
outb(crtc_addr,0x0e);
1115
outb(crtc_addr+1,(address&0xff00)>>8);
1116
outb(crtc_addr,0x0f);
1117
outb(crtc_addr+1,address&0x00ff);
1121
// --------------------------------------------------------------------------------------------
1122
static void biosfn_get_cursor_pos (page,shape, pos)
1123
Bit8u page;Bit16u *shape;Bit16u *pos;
1128
write_word(ss, shape, 0);
1129
write_word(ss, pos, 0);
1132
// FIXME should handle VGA 14/16 lines
1133
write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE));
1134
write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2));
1137
// --------------------------------------------------------------------------------------------
1138
static void biosfn_set_active_page (page)
1141
Bit16u cursor,dummy,crtc_addr;
1142
Bit16u nbcols,nbrows,address;
1148
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1149
line=find_vga_entry(mode);
1150
if(line==0xFF)return;
1152
// Get pos curs pos for the right page
1153
biosfn_get_cursor_pos(page,&dummy,&cursor);
1155
if(vga_modes[line].class==TEXT)
1157
// Get the dimensions
1158
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1159
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1161
// Calculate the address knowing nbcols nbrows and page num
1162
address=SCREEN_MEM_START(nbcols,nbrows,page);
1163
write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address);
1166
address=SCREEN_IO_START(nbcols,nbrows,page);
1170
address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l);
1173
// CRTC regs 0x0c and 0x0d
1174
crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
1175
outb(crtc_addr,0x0c);
1176
outb(crtc_addr+1,(address&0xff00)>>8);
1177
outb(crtc_addr,0x0d);
1178
outb(crtc_addr+1,address&0x00ff);
1180
// And change the BIOS page
1181
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page);
1184
printf("Set active page %02x address %04x\n",page,address);
1187
// Display the cursor, now the page is active
1188
biosfn_set_cursor_pos(page,cursor);
1191
// --------------------------------------------------------------------------------------------
1192
static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight)
1193
Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;
1198
src=ysrc*cheight*nbcols+xstart;
1199
dest=ydest*cheight*nbcols+xstart;
1200
outw(VGAREG_GRDC_ADDRESS, 0x0105);
1201
for(i=0;i<cheight;i++)
1203
memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols);
1205
outw(VGAREG_GRDC_ADDRESS, 0x0005);
1208
// --------------------------------------------------------------------------------------------
1209
static void vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr)
1210
Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;
1215
dest=ystart*cheight*nbcols+xstart;
1216
outw(VGAREG_GRDC_ADDRESS, 0x0205);
1217
for(i=0;i<cheight;i++)
1219
memsetb(0xa000,dest+i*nbcols,attr,cols);
1221
outw(VGAREG_GRDC_ADDRESS, 0x0005);
1224
// --------------------------------------------------------------------------------------------
1225
static void vgamem_copy_cga(xstart,ysrc,ydest,cols,nbcols,cheight)
1226
Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight;
1231
src=((ysrc*cheight*nbcols)>>1)+xstart;
1232
dest=((ydest*cheight*nbcols)>>1)+xstart;
1233
for(i=0;i<cheight;i++)
1236
memcpyb(0xb800,0x2000+dest+(i>>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols);
1238
memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols);
1242
// --------------------------------------------------------------------------------------------
1243
static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr)
1244
Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr;
1249
dest=((ystart*cheight*nbcols)>>1)+xstart;
1250
for(i=0;i<cheight;i++)
1253
memsetb(0xb800,0x2000+dest+(i>>1)*nbcols,attr,cols);
1255
memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols);
1259
// --------------------------------------------------------------------------------------------
1260
static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
1261
Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir;
1263
// page == 0xFF if current
1265
Bit8u mode,line,cheight,bpp,cols;
1266
Bit16u nbcols,nbrows,i;
1273
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1274
line=find_vga_entry(mode);
1275
if(line==0xFF)return;
1277
// Get the dimensions
1278
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1279
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1281
// Get the current page
1283
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1285
if(rlr>=nbrows)rlr=nbrows-1;
1286
if(clr>=nbcols)clr=nbcols-1;
1287
if(nblines>nbrows)nblines=0;
1290
if(vga_modes[line].class==TEXT)
1292
// Compute the address
1293
address=SCREEN_MEM_START(nbcols,nbrows,page);
1295
printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page);
1298
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1300
memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols);
1305
{for(i=rul;i<=rlr;i++)
1307
if((i+nblines>rlr)||(nblines==0))
1308
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
1310
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols);
1314
{for(i=rlr;i>=rul;i--)
1316
if((i<rul+nblines)||(nblines==0))
1317
memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols);
1319
memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols);
1327
// FIXME gfx mode not complete
1328
cheight=video_param_table[line_to_vpti[line]].cheight;
1329
switch(vga_modes[line].memmodel)
1333
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1335
outw(VGAREG_GRDC_ADDRESS, 0x0205);
1336
memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight);
1337
outw(VGAREG_GRDC_ADDRESS, 0x0005);
1342
{for(i=rul;i<=rlr;i++)
1344
if((i+nblines>rlr)||(nblines==0))
1345
vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
1347
vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight);
1351
{for(i=rlr;i>=rul;i--)
1353
if((i<rul+nblines)||(nblines==0))
1354
vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
1356
vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight);
1363
bpp=vga_modes[line].pixbits;
1364
if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1)
1366
memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp);
1378
{for(i=rul;i<=rlr;i++)
1380
if((i+nblines>rlr)||(nblines==0))
1381
vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);
1383
vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight);
1387
{for(i=rlr;i>=rul;i--)
1389
if((i<rul+nblines)||(nblines==0))
1390
vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr);
1392
vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight);
1400
printf("Scroll in graphics mode ");
1407
// --------------------------------------------------------------------------------------------
1408
static void biosfn_read_char_attr (page,car)
1409
Bit8u page;Bit16u *car;
1410
{Bit16u ss=get_SS();
1411
Bit8u xcurs,ycurs,mode,line;
1412
Bit16u nbcols,nbrows,address;
1413
Bit16u cursor,dummy;
1416
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1417
line=find_vga_entry(mode);
1418
if(line==0xFF)return;
1420
// Get the cursor pos for the page
1421
biosfn_get_cursor_pos(page,&dummy,&cursor);
1422
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1424
// Get the dimensions
1425
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1426
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1428
if(vga_modes[line].class==TEXT)
1430
// Compute the address
1431
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1433
write_word(ss,car,read_word(vga_modes[line].sstart,address));
1444
// --------------------------------------------------------------------------------------------
1445
static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight)
1446
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight;
1450
Bit16u addr,dest,src;
1462
addr=xcurs+ycurs*cheight*nbcols;
1463
src = car * cheight;
1464
outw(VGAREG_SEQU_ADDRESS, 0x0f02);
1465
outw(VGAREG_GRDC_ADDRESS, 0x0205);
1468
outw(VGAREG_GRDC_ADDRESS, 0x1803);
1472
outw(VGAREG_GRDC_ADDRESS, 0x0003);
1474
for(i=0;i<cheight;i++)
1480
outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
1481
read_byte(0xa000,dest);
1482
if(fdata[src+i]&mask)
1484
write_byte(0xa000,dest,attr&0x0f);
1488
write_byte(0xa000,dest,0x00);
1493
mov dx, # VGAREG_GRDC_ADDRESS
1503
// --------------------------------------------------------------------------------------------
1504
static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp)
1505
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp;
1507
Bit8u i,j,mask,data;
1509
Bit16u addr,dest,src;
1512
addr=(xcurs*bpp)+ycurs*320;
1516
dest=addr+(i>>1)*80;
1517
if (i & 1) dest += 0x2000;
1523
data = read_byte(0xb800,dest);
1531
if (fdata[src+i] & mask)
1535
data ^= (attr & 0x01) << (7-j);
1539
data |= (attr & 0x01) << (7-j);
1544
write_byte(0xb800,dest,data);
1552
data = read_byte(0xb800,dest);
1560
if (fdata[src+i] & mask)
1564
data ^= (attr & 0x03) << ((3-j)*2);
1568
data |= (attr & 0x03) << ((3-j)*2);
1573
write_byte(0xb800,dest,data);
1580
// --------------------------------------------------------------------------------------------
1581
static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols)
1582
Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;
1584
Bit8u i,j,mask,data;
1586
Bit16u addr,dest,src;
1589
addr=xcurs*8+ycurs*nbcols*64;
1593
dest=addr+i*nbcols*8;
1598
if (fdata[src+i] & mask)
1602
write_byte(0xa000,dest+j,data);
1608
// --------------------------------------------------------------------------------------------
1609
static void biosfn_write_char_attr (car,page,attr,count)
1610
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
1612
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1613
Bit16u nbcols,nbrows,address;
1614
Bit16u cursor,dummy;
1617
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1618
line=find_vga_entry(mode);
1619
if(line==0xFF)return;
1621
// Get the cursor pos for the page
1622
biosfn_get_cursor_pos(page,&dummy,&cursor);
1623
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1625
// Get the dimensions
1626
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1627
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1629
if(vga_modes[line].class==TEXT)
1631
// Compute the address
1632
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1634
dummy=((Bit16u)attr<<8)+car;
1635
memsetw(vga_modes[line].sstart,address,dummy,count);
1639
// FIXME gfx mode not complete
1640
cheight=video_param_table[line_to_vpti[line]].cheight;
1641
bpp=vga_modes[line].pixbits;
1642
while((count-->0) && (xcurs<nbcols))
1644
switch(vga_modes[line].memmodel)
1648
write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
1651
write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
1654
write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
1666
// --------------------------------------------------------------------------------------------
1667
static void biosfn_write_char_only (car,page,attr,count)
1668
Bit8u car;Bit8u page;Bit8u attr;Bit16u count;
1670
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1671
Bit16u nbcols,nbrows,address;
1672
Bit16u cursor,dummy;
1675
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1676
line=find_vga_entry(mode);
1677
if(line==0xFF)return;
1679
// Get the cursor pos for the page
1680
biosfn_get_cursor_pos(page,&dummy,&cursor);
1681
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1683
// Get the dimensions
1684
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1685
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1687
if(vga_modes[line].class==TEXT)
1689
// Compute the address
1690
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
1693
{write_byte(vga_modes[line].sstart,address,car);
1699
// FIXME gfx mode not complete
1700
cheight=video_param_table[line_to_vpti[line]].cheight;
1701
bpp=vga_modes[line].pixbits;
1702
while((count-->0) && (xcurs<nbcols))
1704
switch(vga_modes[line].memmodel)
1708
write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
1711
write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
1714
write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
1726
// --------------------------------------------------------------------------------------------
1730
je biosfn_set_border_color
1732
je biosfn_set_palette
1737
biosfn_set_border_color:
1742
mov dx, # VGAREG_ACTL_RESET
1744
mov dx, # VGAREG_ACTL_ADDRESS
1757
mov dx, # VGAREG_ACTL_ADDRESS
1760
mov dx, # VGAREG_ACTL_READ_DATA
1764
mov dx, # VGAREG_ACTL_ADDRESS
1768
jne set_intensity_loop
1781
mov dx, # VGAREG_ACTL_RESET
1785
set_cga_palette_loop:
1786
mov dx, # VGAREG_ACTL_ADDRESS
1789
mov dx, # VGAREG_ACTL_READ_DATA
1793
mov dx, # VGAREG_ACTL_ADDRESS
1797
jne set_cga_palette_loop
1807
// --------------------------------------------------------------------------------------------
1808
static void biosfn_write_pixel (BH,AL,CX,DX) Bit8u BH;Bit8u AL;Bit16u CX;Bit16u DX;
1810
Bit8u mode,line,mask,attr,data;
1814
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1815
line=find_vga_entry(mode);
1816
if(line==0xFF)return;
1817
if(vga_modes[line].class==TEXT)return;
1819
switch(vga_modes[line].memmodel)
1823
addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1824
mask = 0x80 >> (CX & 0x07);
1825
outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
1826
outw(VGAREG_GRDC_ADDRESS, 0x0205);
1827
data = read_byte(0xa000,addr);
1830
outw(VGAREG_GRDC_ADDRESS, 0x1803);
1832
write_byte(0xa000,addr,AL);
1834
mov dx, # VGAREG_GRDC_ADDRESS
1844
if(vga_modes[line].pixbits==2)
1846
addr=(CX>>2)+(DX>>1)*80;
1850
addr=(CX>>3)+(DX>>1)*80;
1852
if (DX & 1) addr += 0x2000;
1853
data = read_byte(0xb800,addr);
1854
if(vga_modes[line].pixbits==2)
1856
attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2);
1857
mask = 0x03 << ((3 - (CX & 0x03)) * 2);
1861
attr = (AL & 0x01) << (7 - (CX & 0x07));
1862
mask = 0x01 << (7 - (CX & 0x07));
1873
write_byte(0xb800,addr,data);
1876
addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
1877
write_byte(0xa000,addr,AL);
1886
// --------------------------------------------------------------------------------------------
1887
static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX;
1889
Bit8u mode,line,mask,attr,data,i;
1894
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1895
line=find_vga_entry(mode);
1896
if(line==0xFF)return;
1897
if(vga_modes[line].class==TEXT)return;
1899
switch(vga_modes[line].memmodel)
1903
addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1904
mask = 0x80 >> (CX & 0x07);
1908
outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04);
1909
data = read_byte(0xa000,addr) & mask;
1910
if (data > 0) attr |= (0x01 << i);
1914
addr=(CX>>2)+(DX>>1)*80;
1915
if (DX & 1) addr += 0x2000;
1916
data = read_byte(0xb800,addr);
1917
if(vga_modes[line].pixbits==2)
1919
attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03;
1923
attr = (data >> (7 - (CX & 0x07))) & 0x01;
1927
addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
1928
attr=read_byte(0xa000,addr);
1936
write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr);
1939
// --------------------------------------------------------------------------------------------
1940
static void biosfn_write_teletype (car, page, attr, flag)
1941
Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
1942
{// flag = WITH_ATTR / NO_ATTR
1944
Bit8u cheight,xcurs,ycurs,mode,line,bpp;
1945
Bit16u nbcols,nbrows,address;
1946
Bit16u cursor,dummy;
1948
// special case if page is 0xff, use current page
1950
page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
1953
mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE);
1954
line=find_vga_entry(mode);
1955
if(line==0xFF)return;
1957
// Get the cursor pos for the page
1958
biosfn_get_cursor_pos(page,&dummy,&cursor);
1959
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1961
// Get the dimensions
1962
nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
1963
nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
1986
biosfn_write_teletype(' ',page,attr,flag);
1987
biosfn_get_cursor_pos(page,&dummy,&cursor);
1988
xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8;
1994
if(vga_modes[line].class==TEXT)
1996
// Compute the address
1997
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2;
2000
write_byte(vga_modes[line].sstart,address,car);
2003
write_byte(vga_modes[line].sstart,address+1,attr);
2007
// FIXME gfx mode not complete
2008
cheight=video_param_table[line_to_vpti[line]].cheight;
2009
bpp=vga_modes[line].pixbits;
2010
switch(vga_modes[line].memmodel)
2014
write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
2017
write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp);
2020
write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
2031
// Do we need to wrap ?
2037
// Do we need to scroll ?
2040
if(vga_modes[line].class==TEXT)
2042
address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2;
2043
attr=read_byte(vga_modes[line].sstart,address+1);
2044
biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
2048
biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
2053
// Set the cursor for the page
2054
cursor=ycurs; cursor<<=8; cursor+=xcurs;
2055
biosfn_set_cursor_pos(page,cursor);
2058
// --------------------------------------------------------------------------------------------
2060
biosfn_get_video_mode:
2062
mov ax, # BIOSMEM_SEG
2065
mov bx, # BIOSMEM_CURRENT_PAGE
2070
mov bx, # BIOSMEM_VIDEO_CTL
2073
mov bx, # BIOSMEM_CURRENT_MODE
2076
mov bx, # BIOSMEM_NB_COLS
2083
// --------------------------------------------------------------------------------------------
2088
jmp biosfn_set_single_palette_reg
2092
jmp biosfn_set_overscan_border_color
2096
jmp biosfn_set_all_palette_reg
2100
jmp biosfn_toggle_intensity
2104
jmp biosfn_get_single_palette_reg
2108
jmp biosfn_read_overscan_border_color
2112
jmp biosfn_get_all_palette_reg
2116
jmp biosfn_set_single_dac_reg
2120
jmp biosfn_set_all_dac_reg
2124
jmp biosfn_select_video_dac_color_page
2128
jmp biosfn_read_single_dac_reg
2132
jmp biosfn_read_all_dac_reg
2136
jmp biosfn_set_pel_mask
2140
jmp biosfn_read_pel_mask
2143
jne int10_group_10_unknown
2144
jmp biosfn_read_video_dac_state
2145
int10_group_10_unknown:
2151
biosfn_set_single_palette_reg:
2156
mov dx, # VGAREG_ACTL_RESET
2158
mov dx, # VGAREG_ACTL_ADDRESS
2171
// --------------------------------------------------------------------------------------------
2173
biosfn_set_overscan_border_color:
2176
call biosfn_set_single_palette_reg
2181
// --------------------------------------------------------------------------------------------
2183
biosfn_set_all_palette_reg:
2189
mov dx, # VGAREG_ACTL_RESET
2192
mov dx, # VGAREG_ACTL_ADDRESS
2202
jne set_palette_loop
2217
// --------------------------------------------------------------------------------------------
2219
biosfn_toggle_intensity:
2223
mov dx, # VGAREG_ACTL_RESET
2225
mov dx, # VGAREG_ACTL_ADDRESS
2228
mov dx, # VGAREG_ACTL_READ_DATA
2234
mov dx, # VGAREG_ACTL_ADDRESS
2244
// --------------------------------------------------------------------------------------------
2246
biosfn_get_single_palette_reg:
2251
mov dx, # VGAREG_ACTL_RESET
2253
mov dx, # VGAREG_ACTL_ADDRESS
2256
mov dx, # VGAREG_ACTL_READ_DATA
2259
mov dx, # VGAREG_ACTL_RESET
2261
mov dx, # VGAREG_ACTL_ADDRESS
2270
// --------------------------------------------------------------------------------------------
2272
biosfn_read_overscan_border_color:
2276
call biosfn_get_single_palette_reg
2284
// --------------------------------------------------------------------------------------------
2286
biosfn_get_all_palette_reg:
2294
mov dx, # VGAREG_ACTL_RESET
2296
mov dx, # VGAREG_ACTL_ADDRESS
2299
mov dx, # VGAREG_ACTL_READ_DATA
2306
jne get_palette_loop
2307
mov dx, # VGAREG_ACTL_RESET
2309
mov dx, # VGAREG_ACTL_ADDRESS
2312
mov dx, # VGAREG_ACTL_READ_DATA
2316
mov dx, # VGAREG_ACTL_RESET
2318
mov dx, # VGAREG_ACTL_ADDRESS
2328
// --------------------------------------------------------------------------------------------
2330
biosfn_set_single_dac_reg:
2333
mov dx, # VGAREG_DAC_WRITE_ADDRESS
2336
mov dx, # VGAREG_DAC_DATA
2350
// --------------------------------------------------------------------------------------------
2352
biosfn_set_all_dac_reg:
2357
mov dx, # VGAREG_DAC_WRITE_ADDRESS
2363
mov dx, # VGAREG_DAC_DATA
2386
// --------------------------------------------------------------------------------------------
2388
biosfn_select_video_dac_color_page:
2392
mov dx, # VGAREG_ACTL_RESET
2394
mov dx, # VGAREG_ACTL_ADDRESS
2397
mov dx, # VGAREG_ACTL_READ_DATA
2404
mov dx, # VGAREG_ACTL_ADDRESS
2409
mov dx, # VGAREG_ACTL_RESET
2411
mov dx, # VGAREG_ACTL_ADDRESS
2431
// --------------------------------------------------------------------------------------------
2433
biosfn_read_single_dac_reg:
2436
mov dx, # VGAREG_DAC_READ_ADDRESS
2441
mov dx, # VGAREG_DAC_DATA
2454
// --------------------------------------------------------------------------------------------
2456
biosfn_read_all_dac_reg:
2461
mov dx, # VGAREG_DAC_READ_ADDRESS
2467
mov dx, # VGAREG_DAC_DATA
2490
// --------------------------------------------------------------------------------------------
2492
biosfn_set_pel_mask:
2495
mov dx, # VGAREG_PEL_MASK
2503
// --------------------------------------------------------------------------------------------
2505
biosfn_read_pel_mask:
2508
mov dx, # VGAREG_PEL_MASK
2516
// --------------------------------------------------------------------------------------------
2518
biosfn_read_video_dac_state:
2521
mov dx, # VGAREG_ACTL_RESET
2523
mov dx, # VGAREG_ACTL_ADDRESS
2526
mov dx, # VGAREG_ACTL_READ_DATA
2530
mov dx, # VGAREG_ACTL_RESET
2532
mov dx, # VGAREG_ACTL_ADDRESS
2535
mov dx, # VGAREG_ACTL_READ_DATA
2543
mov dx, # VGAREG_ACTL_RESET
2545
mov dx, # VGAREG_ACTL_ADDRESS
2553
// --------------------------------------------------------------------------------------------
2554
static void biosfn_perform_gray_scale_summing (start,count)
2555
Bit16u start;Bit16u count;
2560
inb(VGAREG_ACTL_RESET);
2561
outb(VGAREG_ACTL_ADDRESS,0x00);
2563
for( index = 0; index < count; index++ )
2565
// set read address and switch to read mode
2566
outb(VGAREG_DAC_READ_ADDRESS,start);
2567
// get 6-bit wide RGB data values
2568
r=inb( VGAREG_DAC_DATA );
2569
g=inb( VGAREG_DAC_DATA );
2570
b=inb( VGAREG_DAC_DATA );
2572
// intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue )
2573
i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8;
2577
// set write address and switch to write mode
2578
outb(VGAREG_DAC_WRITE_ADDRESS,start);
2579
// write new intensity value
2580
outb( VGAREG_DAC_DATA, i&0xff );
2581
outb( VGAREG_DAC_DATA, i&0xff );
2582
outb( VGAREG_DAC_DATA, i&0xff );
2585
inb(VGAREG_ACTL_RESET);
2586
outb(VGAREG_ACTL_ADDRESS,0x20);
2589
// --------------------------------------------------------------------------------------------
2590
static void get_font_access()
2593
mov dx, # VGAREG_SEQU_ADDRESS
2602
mov dx, # VGAREG_GRDC_ADDRESS
2612
static void release_font_access()
2615
mov dx, # VGAREG_SEQU_ADDRESS
2624
mov dx, # VGAREG_READ_MISC_OUTPUT
2631
mov dx, # VGAREG_GRDC_ADDRESS
2647
static void set_scan_lines(lines) Bit8u lines;
2649
Bit16u crtc_addr,cols,page,vde;
2650
Bit8u crtc_r9,ovl,rows;
2652
crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
2653
outb(crtc_addr, 0x09);
2654
crtc_r9 = inb(crtc_addr+1);
2655
crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
2656
outb(crtc_addr+1, crtc_r9);
2659
biosfn_set_cursor_shape(0x06,0x07);
2663
biosfn_set_cursor_shape(lines-4,lines-3);
2665
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
2666
outb(crtc_addr, 0x12);
2667
vde = inb(crtc_addr+1);
2668
outb(crtc_addr, 0x07);
2669
ovl = inb(crtc_addr+1);
2670
vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
2672
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
2673
cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
2674
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
2677
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;
2679
Bit16u blockaddr,dest,i,src;
2682
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2686
dest = blockaddr + (DX + i) * 32;
2687
memcpyb(0xA000, dest, ES, src, BH);
2689
release_font_access();
2696
static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL;
2698
Bit16u blockaddr,dest,i,src;
2701
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2702
for(i=0;i<0x100;i++)
2705
dest = blockaddr + i * 32;
2706
memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14);
2708
release_font_access();
2715
static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL;
2717
Bit16u blockaddr,dest,i,src;
2720
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2721
for(i=0;i<0x100;i++)
2724
dest = blockaddr + i * 32;
2725
memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8);
2727
release_font_access();
2734
// --------------------------------------------------------------------------------------------
2736
biosfn_set_text_block_specifier:
2739
mov dx, # VGAREG_SEQU_ADDRESS
2748
// --------------------------------------------------------------------------------------------
2749
static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL;
2751
Bit16u blockaddr,dest,i,src;
2754
blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
2755
for(i=0;i<0x100;i++)
2758
dest = blockaddr + i * 32;
2759
memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
2761
release_font_access();
2768
static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP;
2774
static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL;
2780
static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL;
2786
static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL;
2792
static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL;
2798
// --------------------------------------------------------------------------------------------
2799
static void biosfn_get_font_info (BH,ES,BP,CX,DX)
2800
Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX;
2801
{Bit16u ss=get_SS();
2805
write_word(ss,ES,read_word(0x00,0x1f*4));
2806
write_word(ss,BP,read_word(0x00,(0x1f*4)+2));
2809
write_word(ss,ES,read_word(0x00,0x43*4));
2810
write_word(ss,BP,read_word(0x00,(0x43*4)+2));
2813
write_word(ss,ES,0xC000);
2814
write_word(ss,BP,vgafont14);
2817
write_word(ss,ES,0xC000);
2818
write_word(ss,BP,vgafont8);
2821
write_word(ss,ES,0xC000);
2822
write_word(ss,BP,vgafont8+128*8);
2825
write_word(ss,ES,0xC000);
2826
write_word(ss,BP,vgafont14alt);
2829
write_word(ss,ES,0xC000);
2830
write_word(ss,BP,vgafont16);
2833
write_word(ss,ES,0xC000);
2834
write_word(ss,BP,vgafont16alt);
2838
printf("Get font info BH(%02x) was discarded\n",BH);
2842
// Set byte/char of on screen font
2843
write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT));
2845
// Set Highest char row
2846
write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS));
2849
// --------------------------------------------------------------------------------------------
2851
biosfn_get_ega_info:
2854
mov ax, # BIOSMEM_SEG
2857
mov bx, # BIOSMEM_SWITCHES
2860
mov bx, # BIOSMEM_CRTC_ADDRESS
2863
cmp ax, # VGAREG_MDA_CRTC_ADDRESS
2872
// --------------------------------------------------------------------------------------------
2873
static void biosfn_alternate_prtsc()
2880
// --------------------------------------------------------------------------------------------
2882
biosfn_select_vert_res:
2884
; res : 00 200 lines, 01 350 lines, 02 400 lines
2890
mov ax, # BIOSMEM_SEG
2892
mov bx, # BIOSMEM_MODESET_CTL
2894
mov bx, # BIOSMEM_SWITCHES
2905
mov bx, #msg_vert_res
2913
; reset modeset ctl bit 7 and set bit 4
2914
; set switches bit 3-0 to 0x09
2923
; reset modeset ctl bit 7 and bit 4
2924
; set switches bit 3-0 to 0x09
2932
; set modeset ctl bit 7 and reset bit 4
2933
; set switches bit 3-0 to 0x08
2940
mov bx, # BIOSMEM_MODESET_CTL
2942
mov bx, # BIOSMEM_SWITCHES
2953
.ascii "Select vert res (%02x) was discarded"
2954
.byte 0x0d,0x0a,0x00
2958
biosfn_enable_default_palette_loading:
2965
mov ax, # BIOSMEM_SEG
2967
mov bx, # BIOSMEM_MODESET_CTL
2979
biosfn_enable_video_addressing:
2986
mov dx, # VGAREG_READ_MISC_OUTPUT
2990
mov dx, # VGAREG_WRITE_MISC_OUTPUT
2998
biosfn_enable_grayscale_summing:
3006
mov ax, # BIOSMEM_SEG
3008
mov bx, # BIOSMEM_MODESET_CTL
3020
biosfn_enable_cursor_emulation:
3027
mov ax, # BIOSMEM_SEG
3029
mov bx, # BIOSMEM_MODESET_CTL
3041
// --------------------------------------------------------------------------------------------
3042
static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX;
3048
static void biosfn_enable_video_refresh_control (AL) Bit8u AL;
3055
// --------------------------------------------------------------------------------------------
3056
static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset)
3057
Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset;
3059
Bit16u newcurs,oldcurs,dummy;
3062
// Read curs info for the page
3063
biosfn_get_cursor_pos(page,&dummy,&oldcurs);
3065
// if row=0xff special case : use current cursor position
3067
{col=oldcurs&0x00ff;
3068
row=(oldcurs&0xff00)>>8;
3071
newcurs=row; newcurs<<=8; newcurs+=col;
3072
biosfn_set_cursor_pos(page,newcurs);
3076
car=read_byte(seg,offset++);
3078
attr=read_byte(seg,offset++);
3080
biosfn_write_teletype(car,page,attr,WITH_ATTR);
3083
// Set back curs pos
3085
biosfn_set_cursor_pos(page,oldcurs);
3088
// --------------------------------------------------------------------------------------------
3092
je biosfn_read_display_code
3094
je biosfn_set_display_code
3099
biosfn_read_display_code:
3102
mov ax, # BIOSMEM_SEG
3104
mov bx, # BIOSMEM_DCC_INDEX
3112
biosfn_set_display_code:
3116
mov ax, # BIOSMEM_SEG
3119
mov bx, # BIOSMEM_DCC_INDEX
3125
mov bx, #msg_alt_dcc
3138
.ascii "Alternate Display code (%02x) was discarded"
3139
.byte 0x0d,0x0a,0x00
3143
// --------------------------------------------------------------------------------------------
3144
static void biosfn_read_state_info (BX,ES,DI)
3145
Bit16u BX;Bit16u ES;Bit16u DI;
3147
// Address of static functionality table
3148
write_word(ES,DI+0x00,&static_functionality);
3149
write_word(ES,DI+0x02,0xC000);
3151
// Hard coded copy from BIOS area. Should it be cleaner ?
3152
memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30);
3153
memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3);
3155
write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX));
3156
write_byte(ES,DI+0x26,0);
3157
write_byte(ES,DI+0x27,16);
3158
write_byte(ES,DI+0x28,0);
3159
write_byte(ES,DI+0x29,8);
3160
write_byte(ES,DI+0x2a,2);
3161
write_byte(ES,DI+0x2b,0);
3162
write_byte(ES,DI+0x2c,0);
3163
write_byte(ES,DI+0x31,3);
3164
write_byte(ES,DI+0x32,0);
3166
memsetb(ES,DI+0x33,0,13);
3169
// --------------------------------------------------------------------------------------------
3170
// --------------------------------------------------------------------------------------------
3171
static Bit16u biosfn_read_video_state_size2 (CX)
3180
size += (5 + 8 + 5) * 2 + 6;
3183
size += 3 + 256 * 3 + 1;
3188
static void biosfn_read_video_state_size (CX, BX)
3189
Bit16u CX; Bit16u *BX;
3192
write_word(ss, BX, biosfn_read_video_state_size2(CX));
3195
static Bit16u biosfn_save_video_state (CX,ES,BX)
3196
Bit16u CX;Bit16u ES;Bit16u BX;
3198
Bit16u i, v, crtc_addr, ar_index;
3200
crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
3202
write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++;
3203
write_byte(ES, BX, inb(crtc_addr)); BX++;
3204
write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++;
3205
inb(VGAREG_ACTL_RESET);
3206
ar_index = inb(VGAREG_ACTL_ADDRESS);
3207
write_byte(ES, BX, ar_index); BX++;
3208
write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++;
3211
outb(VGAREG_SEQU_ADDRESS, i);
3212
write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
3214
outb(VGAREG_SEQU_ADDRESS, 0);
3215
write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++;
3217
for(i=0;i<=0x18;i++) {
3219
write_byte(ES, BX, inb(crtc_addr+1)); BX++;
3222
for(i=0;i<=0x13;i++) {
3223
inb(VGAREG_ACTL_RESET);
3224
outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
3225
write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++;
3227
inb(VGAREG_ACTL_RESET);
3230
outb(VGAREG_GRDC_ADDRESS,i);
3231
write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++;
3234
write_word(ES, BX, crtc_addr); BX+= 2;
3236
/* XXX: read plane latches */
3237
write_byte(ES, BX, 0); BX++;
3238
write_byte(ES, BX, 0); BX++;
3239
write_byte(ES, BX, 0); BX++;
3240
write_byte(ES, BX, 0); BX++;
3243
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++;
3244
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2;
3245
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2;
3246
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2;
3247
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++;
3248
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2;
3249
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++;
3250
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++;
3251
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++;
3252
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2;
3254
write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i));
3257
write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2;
3258
write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++;
3260
write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2;
3261
write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2;
3262
write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2;
3263
write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2;
3266
/* XXX: check this */
3267
write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */
3268
write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */
3269
write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++;
3270
// Set the whole dac always, from 0
3271
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
3272
for(i=0;i<256*3;i++) {
3273
write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++;
3275
write_byte(ES, BX, 0); BX++; /* color select register */
3280
static Bit16u biosfn_restore_video_state (CX,ES,BX)
3281
Bit16u CX;Bit16u ES;Bit16u BX;
3283
Bit16u i, crtc_addr, v, addr1, ar_index;
3286
// Reset Attribute Ctl flip-flop
3287
inb(VGAREG_ACTL_RESET);
3289
crtc_addr = read_word(ES, BX + 0x40);
3294
outb(VGAREG_SEQU_ADDRESS, i);
3295
outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
3297
outb(VGAREG_SEQU_ADDRESS, 0);
3298
outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++;
3300
// Disable CRTC write protection
3301
outw(crtc_addr,0x0011);
3303
for(i=0;i<=0x18;i++) {
3306
outb(crtc_addr+1, read_byte(ES, BX));
3310
// select crtc base address
3311
v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01;
3312
if (crtc_addr = 0x3d4)
3314
outb(VGAREG_WRITE_MISC_OUTPUT, v);
3316
// enable write protection if needed
3317
outb(crtc_addr, 0x11);
3318
outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11));
3320
// Set Attribute Ctl
3321
ar_index = read_byte(ES, addr1 + 0x03);
3322
inb(VGAREG_ACTL_RESET);
3323
for(i=0;i<=0x13;i++) {
3324
outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20));
3325
outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++;
3327
outb(VGAREG_ACTL_ADDRESS, ar_index);
3328
inb(VGAREG_ACTL_RESET);
3331
outb(VGAREG_GRDC_ADDRESS,i);
3332
outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++;
3334
BX += 2; /* crtc_addr */
3335
BX += 4; /* plane latches */
3337
outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++;
3338
outb(crtc_addr, read_byte(ES, addr1)); addr1++;
3339
outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++;
3341
outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++;
3344
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++;
3345
write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2;
3346
write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2;
3347
write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2;
3348
write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++;
3349
write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2;
3350
write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++;
3351
write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++;
3352
write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++;
3353
write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2;
3355
write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX));
3358
write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2;
3359
write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++;
3361
write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2;
3362
write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2;
3363
write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2;
3364
write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2;
3368
v = read_byte(ES, BX); BX++;
3369
outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++;
3370
// Set the whole dac always, from 0
3371
outb(VGAREG_DAC_WRITE_ADDRESS,0x00);
3372
for(i=0;i<256*3;i++) {
3373
outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++;
3376
outb(VGAREG_DAC_WRITE_ADDRESS, v);
3381
// ============================================================================================
3385
// ============================================================================================
3387
// --------------------------------------------------------------------------------------------
3388
static Bit8u find_vga_entry(mode)
3392
for(i=0;i<=MODE_MAX;i++)
3393
if(vga_modes[i].svgamode==mode)
3400
/* =========================================================== */
3404
/* =========================================================== */
3406
// --------------------------------------------------------------------------------------------
3407
static void memsetb(seg,offset,value,count)
3422
mov cx, 10[bp] ; count
3425
mov ax, 4[bp] ; segment
3427
mov ax, 6[bp] ; offset
3429
mov al, 8[bp] ; value
3444
// --------------------------------------------------------------------------------------------
3445
static void memsetw(seg,offset,value,count)
3460
mov cx, 10[bp] ; count
3463
mov ax, 4[bp] ; segment
3465
mov ax, 6[bp] ; offset
3467
mov ax, 8[bp] ; value
3482
// --------------------------------------------------------------------------------------------
3483
static void memcpyb(dseg,doffset,sseg,soffset,count)
3501
mov cx, 12[bp] ; count
3504
mov ax, 4[bp] ; dsegment
3506
mov ax, 6[bp] ; doffset
3508
mov ax, 8[bp] ; ssegment
3510
mov ax, 10[bp] ; soffset
3528
// --------------------------------------------------------------------------------------------
3529
static void memcpyw(dseg,doffset,sseg,soffset,count)
3547
mov cx, 12[bp] ; count
3550
mov ax, 4[bp] ; dsegment
3552
mov ax, 6[bp] ; doffset
3554
mov ax, 8[bp] ; ssegment
3556
mov ax, 10[bp] ; soffset
3574
/* =========================================================== */
3576
* These functions where ripped from Kevin's rombios.c
3578
/* =========================================================== */
3580
// --------------------------------------------------------------------------------------------
3582
read_byte(seg, offset)
3592
mov ax, 4[bp] ; segment
3594
mov bx, 6[bp] ; offset
3596
;; al = return value (byte)
3604
// --------------------------------------------------------------------------------------------
3606
read_word(seg, offset)
3616
mov ax, 4[bp] ; segment
3618
mov bx, 6[bp] ; offset
3620
;; ax = return value (word)
3628
// --------------------------------------------------------------------------------------------
3630
write_byte(seg, offset, data)
3642
mov ax, 4[bp] ; segment
3644
mov bx, 6[bp] ; offset
3645
mov al, 8[bp] ; data byte
3646
mov [bx], al ; write data byte
3655
// --------------------------------------------------------------------------------------------
3657
write_word(seg, offset, data)
3669
mov ax, 4[bp] ; segment
3671
mov bx, 6[bp] ; offset
3672
mov ax, 8[bp] ; data word
3673
mov [bx], ax ; write data word
3682
// --------------------------------------------------------------------------------------------
3717
// --------------------------------------------------------------------------------------------
3739
// --------------------------------------------------------------------------------------------
3769
void unimplemented()
3771
printf("--> Unimplemented\n");
3776
printf("--> Unknown int10\n");
3780
// --------------------------------------------------------------------------------------------
3781
#if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG)
3785
Bit8u c, format_char;
3787
unsigned format_width, i;
3789
Bit16u arg_seg, arg, digit, nibble, shift_count;
3797
while (c = read_byte(0xc000, s)) {
3802
else if (in_format) {
3803
if ( (c>='0') && (c<='9') ) {
3804
format_width = (format_width * 10) + (c - '0');
3806
else if (c == 'x') {
3807
arg_ptr++; // increment to next arg
3808
arg = read_word(arg_seg, arg_ptr);
3809
if (format_width == 0)
3812
digit = format_width - 1;
3813
for (i=0; i<format_width; i++) {
3814
nibble = (arg >> (4 * digit)) & 0x000f;
3816
outb(0x0500, nibble + '0');
3818
outb(0x0500, (nibble - 10) + 'A');
3823
//else if (c == 'd') {
3836
; get LFB address from PCI
3837
; in - ax: PCI device vendor
3838
; out - ax: LFB address (high 16 bit)
3839
;; NOTE - may be called in protected mode
3850
jz pci_get_lfb_addr_5
3854
cmp ax, bx ;; check vendor
3855
jz pci_get_lfb_addr_4
3857
cmp cx, #0x200 ;; search bus #0 and #1
3858
jb pci_get_lfb_addr_3
3860
xor dx, dx ;; no LFB
3861
jmp pci_get_lfb_addr_6
3863
mov dl, #0x10 ;; I/O space #0
3866
jnz pci_get_lfb_addr_5
3868
mov dx, ax ;; LFB address
3878
; in - cx: device/function
3882
mov eax, #0x00800000
3901
// --------------------------------------------------------------------------------------------
3904
;; DATA_SEG_DEFS_HERE
3908
.ascii "vgabios ends here"
3912
;; BLOCK_STRINGS_BEGIN