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