2 * BIOS interrupt 10h handler
4 * Copyright 1998 Ove Kåven
5 * Copyright 1998 Joseph Pranevich
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(int);
33 static void scroll_window(int direction
, char lines
, char row1
,
34 char col1
, char row2
, char col2
, char attribute
);
39 static void BIOS_GetCursorPos(BIOSDATA
*data
,unsigned page
,unsigned*X
,unsigned*Y
)
41 *X
= data
->VideoCursorPos
[page
*2]; /* column */
42 *Y
= data
->VideoCursorPos
[page
*2+1]; /* row */
45 static void BIOS_SetCursorPos(BIOSDATA
*data
,unsigned page
,unsigned X
,unsigned Y
)
47 data
->VideoCursorPos
[page
*2] = X
;
48 data
->VideoCursorPos
[page
*2+1] = Y
;
52 /**********************************************************************
53 * DOSVM_InitializeVideoMode
55 * The first time this function is called VGA emulation is set to the
58 static void DOSVM_InitializeVideoMode( BIOSDATA
*data
)
60 static BOOL already_initialized
= FALSE
;
64 if(already_initialized
)
66 already_initialized
= TRUE
;
68 VGA_InitAlphaMode(&width
, &height
);
71 * FIXME: Add more mappings between initial size and
74 if (width
>= 80 && height
>= 25) {
75 VGA_SetAlphaMode(80, 25);
76 data
->VideoColumns
= 80;
77 data
->VideoMode
= 0x03;
79 VGA_SetAlphaMode(40, 25);
80 data
->VideoColumns
= 40;
81 data
->VideoMode
= 0x01;
86 /**********************************************************************
87 * DOSVM_Int10Handler (WPROCS.116)
88 * DOSVM_Int10Handler (WINEDOS16.116)
90 * Handler for int 10h (video).
93 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
94 * are present in this list. (SVGA and XGA are not) That is not
95 * to say that all these functions should be supported, but if
96 * anyone is brain-damaged enough to want to emulate one of these
97 * beasts then this should get you started.
100 * Several common graphical extensions used by Microsoft hook
101 * off of here. I have *not* added them to this list (yet). They
104 * MSHERC.COM - More functionality for Hercules cards.
105 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
107 * Yes, MS also added this support into their mouse driver. Don't
108 * ask me, I don't work for them.
110 * Joseph Pranevich - 9/98
113 * Added support for Vesa. It is not complete but is a start.
114 * NOTE: Im not sure if i did all this right or if eny of it works.
115 * Currently i dont have a program that uses Vesa that actually gets far
116 * enough without crashing to do vesa stuff.
118 * Added additional vga graphic support - 3/99
121 static void DOSVM_Int10Handler_VESA( CONTEXT86
*context
)
123 BIOSDATA
*data
= BIOS_DATA
;
125 switch(AL_reg(context
)) {
127 case 0x00: /* GET SuperVGA INFORMATION */
128 TRACE("VESA GET SuperVGA INFORMATION\n");
129 memcpy(CTX_SEG_OFF_TO_LIN(context
,context
->SegEs
,context
->Edi
),
130 &BIOS_EXTRA_PTR
->vesa_info
, sizeof(VESAINFO
));
131 SET_AL( context
, 0x4f );
132 SET_AH( context
, 0x00 ); /* 0x00 = successful 0x01 = failed */
135 case 0x01: /* GET SuperVGA MODE INFORMATION */
136 FIXME("VESA GET SuperVGA Mode Information - Not supported\n");
137 SET_AL( context
, 0x4f );
138 SET_AH( context
, 0x01 ); /* 0x00 = successful 0x01 = failed */
141 case 0x02: /* SET SuperVGA VIDEO MODE */
142 switch(BX_reg(context
)) {
143 /* OEM Video Modes */
144 case 0x00: /* 40x25 */
146 TRACE("Set VESA Text Mode - 0x0%x\n",
148 VGA_SetAlphaMode(40, 25);
149 data
->VideoColumns
= 40;
154 TRACE("Set VESA Text Mode - 0x0%x\n",
156 VGA_SetAlphaMode(80, 25);
157 data
->VideoColumns
= 80;
160 TRACE("Setting VESA 320x200 16-color mode\n");
161 VGA_SetMode(320,200,4);
164 TRACE("Setting VESA 640x200 16-color mode\n");
165 VGA_SetMode(640,200,4);
168 TRACE("Setting VESA 640x350 16-color mode\n");
169 VGA_SetMode(640,350,4);
172 TRACE("Setting VESA 640x480 16-color mode\n");
173 VGA_SetMode(640,480,4);
176 TRACE("Setting VESA 320x200 256-color mode\n");
177 VGA_SetMode(320,200,8);
181 TRACE("Setting VESA 640x400 256-color mode\n");
182 VGA_SetMode(640,400,8);
185 TRACE("Setting VESA 640x480 256-color mode\n");
186 VGA_SetMode(640,480,8);
189 TRACE("Setting VESA 800x600 16-color mode\n");
190 VGA_SetMode(800,600,4);
193 TRACE("Setting VESA 800x600 256-color mode\n");
194 VGA_SetMode(800,600,8);
197 TRACE("Setting VESA 1024x768 16-color mode\n");
198 VGA_SetMode(1024,768,4);
201 TRACE("Setting VESA 1024x768 256-color mode\n");
202 VGA_SetMode(1024,768,8);
205 TRACE("Setting VESA 1280x1024 16-color mode\n");
206 VGA_SetMode(1280,1024,4);
209 TRACE("Setting VESA 1280x1024 256-color mode\n");
210 VGA_SetMode(1280,1024,8);
212 /* 108h - 10Ch are text modes and im lazy so :p */
215 TRACE("Setting VESA 320x200 15bpp\n");
216 VGA_SetMode(320,200,15);
219 TRACE("Setting VESA 320x200 16bpp\n");
220 VGA_SetMode(320,200,16);
223 TRACE("Setting VESA 320x200 24bpp\n");
224 VGA_SetMode(320,200,24);
227 TRACE("Setting VESA 640x480 15bpp\n");
228 VGA_SetMode(640,480,15);
231 TRACE("Setting VESA 640x480 16bpp\n");
232 VGA_SetMode(640,480,16);
235 TRACE("Setting VESA 640x480 24bpp\n");
236 VGA_SetMode(640,480,24);
239 TRACE("Setting VESA 800x600 15bpp\n");
240 VGA_SetMode(800,600,15);
243 TRACE("Setting VESA 800x600 16bpp\n");
244 VGA_SetMode(800,600,16);
247 TRACE("Setting VESA 800x600 24bpp\n");
248 VGA_SetMode(800,600,24);
251 TRACE("Setting VESA 1024x768 15bpp\n");
252 VGA_SetMode(1024,768,15);
255 TRACE("Setting VESA 1024x768 16bpp\n");
256 VGA_SetMode(1024,768,16);
259 TRACE("Setting VESA 1024x768 24bpp\n");
260 VGA_SetMode(1024,768,24);
263 TRACE("Setting VESA 1280x1024 15bpp\n");
264 VGA_SetMode(1280,1024,15);
267 TRACE("Setting VESA 1280x1024 16bpp\n");
268 VGA_SetMode(1280,1024,16);
271 TRACE("Setting VESA 1280x1024 24bpp\n");
272 VGA_SetMode(1280,1024,24);
275 FIXME("VESA Set Video Mode (0x%x) - Not Supported\n", BX_reg(context
));
277 data
->VideoMode
= BX_reg(context
);
278 SET_AL( context
, 0x4f );
279 SET_AH( context
, 0x00 );
282 case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
283 SET_AL( context
, 0x4f );
284 SET_AH( context
, 0x00 ); /* should probly check if a vesa mode has ben set */
285 SET_BX( context
, data
->VideoMode
);
288 case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
289 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
290 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
291 /* maybe we should do this instead ? */
292 /* AH_reg(context = 0x01; not implemented so just fail */
295 case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
297 * This subfunction supports only Window A (BL_reg == 0) and
298 * is assumes that window granularity is 64k.
300 switch(BH_reg(context
)) {
301 case 0x00: /* select video memory window */
302 SET_AL( context
, 0x4f ); /* function supported */
303 if(BL_reg(context
) == 0) {
304 VGA_SetWindowStart(DX_reg(context
) * 64 * 1024);
305 SET_AH( context
, 0x00 ); /* status: successful */
307 SET_AH( context
, 0x01 ); /* status: failed */
309 case 0x01: /* get video memory window */
310 SET_AL( context
, 0x4f ); /* function supported */
311 if(BL_reg(context
) == 0) {
312 SET_DX( context
, VGA_GetWindowStart() / 64 / 1024 );
313 SET_AH( context
, 0x00 ); /* status: successful */
315 SET_AH( context
, 0x01 ); /* status: failed */
318 INT_BARF( context
, 0x10 );
322 case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
323 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
324 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
325 /* maybe we should do this instead ? */
326 /* AH_reg(context = 0x001; not implemented so just fail */
329 case 0x07: /* GET/SET DISPLAY START */
330 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
331 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
332 /* maybe we should do this instead ? */
333 /* AH_reg(context = 0x001; not implemented so just fail */
336 case 0x08: /* GET/SET DAC PALETTE CONTROL */
337 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
338 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
339 /* maybe we should do this instead ? */
340 /* AH_reg(context = 0x001; not implemented so just fail */
343 case 0x09: /* SET PALETTE ENTRIES */
344 FIXME("VESA Set palette entries - not implemented\n");
347 case 0x0a: /* GET PROTECTED-MODE CODE */
348 FIXME("VESA Get protected-mode code - not implemented\n");
351 case 0x10: /* Display Power Management Extensions */
352 FIXME("VESA Display Power Management Extensions - not implemented\n");
355 case 0xef: /* get video mode for hercules-compatibles */
356 /* There's no reason to really support this */
357 /* is there?....................(A.C.) */
358 TRACE("Just report the video not hercules compatible\n");
359 SET_DX( context
, 0xffff );
362 case 0xff: /* Turn VESA ON/OFF */
363 /* i dont know what to do */
367 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context
));
372 /**********************************************************************/
374 void WINAPI
DOSVM_Int10Handler( CONTEXT86
*context
)
376 BIOSDATA
*data
= BIOS_DATA
;
378 DOSVM_InitializeVideoMode( data
);
380 switch(AH_reg(context
)) {
382 case 0x00: /* SET VIDEO MODE */
384 /* (mode) (text rows/cols)
388 0x03 - 80x25 or 80x43 or 80x50 (assume 80x25)
392 /* Bit 7 of AH = 0 -> Clean the video memory
395 if (!(AL_reg(context
)&0x80)) {
396 /* FIXME: Do something which cleans the video memory */
399 /* FIXME: Should we keep the bit 7 in the Bios Data memory? */
400 context
->Eax
&= ~0x80;
402 switch (AL_reg(context
)) {
403 case 0x00: /* 40x25 */
405 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
407 VGA_SetAlphaMode(40, 25);
408 data
->VideoColumns
= 40;
413 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
415 VGA_SetAlphaMode(80, 25);
416 data
->VideoColumns
= 80;
419 TRACE("Setting VGA 320x200 16-color mode\n");
420 VGA_SetMode(320,200,4);
423 TRACE("Setting VGA 640x200 16-color mode\n");
424 VGA_SetMode(640,200,4);
427 TRACE("Setting VGA 640x350 16-color mode\n");
428 VGA_SetMode(640,350,4);
431 TRACE("Setting VGA 640x480 16-color mode\n");
432 VGA_SetMode(640,480,4);
435 TRACE("Setting VGA 320x200 256-color mode\n");
436 VGA_SetMode(320,200,8);
439 FIXME("Set Video Mode (0x%x) - Not Supported\n",
442 data
->VideoMode
= AL_reg(context
);
445 case 0x01: /* SET CURSOR SHAPE */
446 TRACE("Set Cursor Shape start %d end %d options %d\n",
447 CH_reg(context
) & 0x1f,
448 CL_reg(context
) & 0x1f,
449 CH_reg(context
) & 0xe0);
450 data
->VideoCursorType
= CX_reg(context
); /* direct copy */
451 VGA_SetCursorShape(CH_reg(context
), CL_reg(context
));
454 case 0x02: /* SET CURSOR POSITION */
455 /* BH = Page Number */ /* Not supported */
456 /* DH = Row */ /* 0 is left */
457 /* DL = Column */ /* 0 is top */
458 BIOS_SetCursorPos(data
,BH_reg(context
),DL_reg(context
),DH_reg(context
));
461 FIXME("Set Cursor Position: Cannot set to page %d\n",
466 VGA_SetCursorPos(DL_reg(context
), DH_reg(context
));
467 TRACE("Set Cursor Position: %d/%d\n", DL_reg(context
),
472 case 0x03: /* GET CURSOR POSITION AND SIZE */
476 TRACE("Get cursor position and size (page %d)\n", BH_reg(context
));
477 SET_CX( context
, data
->VideoCursorType
);
478 BIOS_GetCursorPos(data
,BH_reg(context
),&col
,&row
);
479 SET_DH( context
, row
);
480 SET_DL( context
, col
);
481 TRACE("Cursor Position: %d/%d\n", DL_reg(context
), DH_reg(context
));
485 case 0x04: /* READ LIGHT PEN POSITION */
486 FIXME("Read Light Pen Position - Not Supported\n");
487 SET_AH( context
, 0x00 ); /* Not down */
490 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
491 FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context
));
492 data
->VideoCurPage
= AL_reg(context
);
495 case 0x06: /* SCROLL UP WINDOW */
496 /* AL = Lines to scroll */
498 /* CH,CL = row, col upper-left */
499 /* DH,DL = row, col lower-right */
500 scroll_window(SCROLL_UP
, AL_reg(context
), CH_reg(context
),
501 CL_reg(context
), DH_reg(context
), DL_reg(context
),
503 TRACE("Scroll Up Window %d\n", AL_reg(context
));
506 case 0x07: /* SCROLL DOWN WINDOW */
507 /* AL = Lines to scroll */
509 /* CH,CL = row, col upper-left */
510 /* DH,DL = row, col lower-right */
511 scroll_window(SCROLL_DOWN
, AL_reg(context
), CH_reg(context
),
512 CL_reg(context
), DH_reg(context
), DL_reg(context
),
514 TRACE("Scroll Down Window %d\n", AL_reg(context
));
517 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
519 if (BH_reg(context
)) /* Write to different page */
521 FIXME("Read character and attribute at cursor position -"
522 " Can't read from non-0 page\n");
523 SET_AL( context
, ' ' ); /* That page is blank */
524 SET_AH( context
, 7 );
529 TRACE("Read Character and Attribute at Cursor Position\n");
530 VGA_GetCharacterAtCursor(&ascii
, &attr
);
531 SET_AL( context
, ascii
);
532 SET_AH( context
, attr
);
537 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
538 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
539 /* AL = Character to display. */
540 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
541 /* BL = Attribute / Color */
542 /* CX = Times to Write Char */
543 /* Note here that the cursor is not advanced. */
547 BIOS_GetCursorPos(data
,BH_reg(context
),&col
,&row
);
548 VGA_WriteChars(col
, row
,
550 (AH_reg(context
) == 0x09) ? BL_reg(context
) : -1,
552 if (CX_reg(context
) > 1)
553 TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
554 (AH_reg(context
) == 0x09) ? " and Attribute" : "",
555 CX_reg(context
), AL_reg(context
));
557 TRACE("Write Character%s at Cursor Position: %c\n",
558 (AH_reg(context
) == 0x09) ? " and Attribute" : "",
564 switch BH_reg(context
) {
565 case 0x00: /* SET BACKGROUND/BORDER COLOR */
566 /* In text modes, this sets only the border... */
567 /* According to the interrupt list and one of my books. */
568 /* Funny though that Beyond Zork seems to indicate that it
569 also sets up the default background attributes for clears
571 /* Bear in mind here that we do not want to change,
572 apparently, the foreground or attribute of the background
573 with this call, so we should check first to see what the
574 foreground already is... FIXME */
575 FIXME("Set Background/Border Color: %d/%d\n",
576 BH_reg(context
), BL_reg(context
));
578 case 0x01: /* SET PALETTE */
579 FIXME("Set Palette - Not Supported\n");
582 FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
588 case 0x0c: /* WRITE GRAPHICS PIXEL */
589 /* Not in graphics mode, can ignore w/o error */
590 FIXME("Write Graphics Pixel - Not Supported\n");
593 case 0x0d: /* READ GRAPHICS PIXEL */
594 /* Not in graphics mode, can ignore w/o error */
595 FIXME("Read Graphics Pixel - Not Supported\n");
598 case 0x0e: /* TELETYPE OUTPUT */
599 TRACE("Teletype Output\n");
600 DOSVM_PutChar(AL_reg(context
));
603 case 0x0f: /* GET CURRENT VIDEO MODE */
604 TRACE("Get current video mode: -> mode %d, columns %d\n", data
->VideoMode
, data
->VideoColumns
);
605 /* Note: This should not be a constant value. */
606 SET_AL( context
, data
->VideoMode
);
607 SET_AH( context
, data
->VideoColumns
);
608 SET_BH( context
, 0 ); /* Display page 0 */
612 switch AL_reg(context
) {
613 case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
614 TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
615 BL_reg(context
),BH_reg(context
));
616 /* BH is the value BL is the register */
617 VGA_SetColor16((int)BL_reg(context
),(int)BH_reg(context
));
619 case 0x01: /* SET BORDER (OVERSCAN) */
620 /* Text terminals have no overscan */
621 /* I'm setting it anyway. - A.C. */
622 TRACE("Set Border (Overscan) - Ignored but set.\n");
623 VGA_SetColor16(16,(int)BH_reg(context
));
625 case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
626 TRACE("Set all palette registers\n");
627 /* ES:DX points to a 17 byte table of colors */
628 /* No return data listed */
629 /* I'll have to update my table and the default palette */
630 VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context
, context
->SegEs
, context
->Edx
));
632 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
633 FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
635 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
636 TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context
));
637 /* BL is register to read [ 0-15 ] BH is return value */
638 SET_BH( context
, VGA_GetColor16((int)BL_reg(context
)) );
640 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
641 TRACE("Read Overscan (Border Color) Register \n");
642 SET_BH( context
, VGA_GetColor16(16) );
644 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
645 TRACE("Read All Palette Registers and Overscan Register \n");
646 /* ES:DX points to a 17 byte table where the results */
647 /* of this call should be stored. */
648 VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context
, context
->SegEs
, context
->Edx
));
650 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
654 TRACE("Set Individual DAC register\n");
655 paldat
.peRed
= DH_reg(context
);
656 paldat
.peGreen
= CH_reg(context
);
657 paldat
.peBlue
= CL_reg(context
);
659 VGA_SetPalette(&paldat
,BX_reg(context
)&0xFF,1);
662 case 0x12: /* SET BLOCK OF DAC REGISTERS */
668 TRACE("Set Block of DAC registers\n");
669 pt
= (BYTE
*)CTX_SEG_OFF_TO_LIN(context
,context
->SegEs
,context
->Edx
);
670 for (i
=0;i
<CX_reg(context
);i
++)
672 paldat
.peRed
= (*(pt
+i
*3+0)) << 2;
673 paldat
.peGreen
= (*(pt
+i
*3+1)) << 2;
674 paldat
.peBlue
= (*(pt
+i
*3+2)) << 2;
676 VGA_SetPalette(&paldat
,(BX_reg(context
)+i
)&0xFF,1);
680 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
681 FIXME("Select video DAC color page - Not Supported\n");
683 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
684 FIXME("Read individual DAC register - Not Supported\n");
686 case 0x17: /* READ BLOCK OF DAC REGISTERS */
687 FIXME("Read block of DAC registers - Not Supported\n");
689 case 0x18: /* SET PEL MASK */
690 FIXME("Set PEL mask - Not Supported\n");
692 case 0x19: /* READ PEL MASK */
693 FIXME("Read PEL mask - Not Supported\n");
695 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
696 FIXME("Get video DAC color page state - Not Supported\n");
698 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
699 FIXME("Perform Gray-scale summing - Not Supported\n");
702 FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
708 case 0x11: /* TEXT MODE CHARGEN */
709 /* Note that second subfunction is *almost* identical. */
710 /* See INTERRUPT.A for details. */
711 switch AL_reg(context
) {
712 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
714 FIXME("Load User Specified Patterns - Not Supported\n");
716 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
718 FIXME("Load ROM Monochrome Patterns - Not Supported\n");
720 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
723 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
725 case 0x03: /* SET BLOCK SPECIFIER */
726 FIXME("Set Block Specifier - Not Supported\n");
728 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
730 FIXME("Load ROM 8x16 Character Set - Not Supported\n");
732 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
733 FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
735 case 0x21: /* SET USER GRAPICS CHARACTERS */
736 FIXME("Set User Graphics Characters - Not Supported\n");
738 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
739 FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
741 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
743 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
745 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
746 FIXME("Load 8x16 Graphic Chars - Not Supported\n");
748 case 0x30: /* GET FONT INFORMATION */
749 FIXME("Get Font Information - Not Supported\n");
752 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
758 case 0x12: /* ALTERNATE FUNCTION SELECT */
759 switch BL_reg(context
) {
760 case 0x10: /* GET EGA INFO */
761 TRACE("EGA info requested\n");
762 SET_BH( context
, 0x00 ); /* Color screen */
763 SET_BL( context
, data
->ModeOptions
>> 5 ); /* EGA memory size */
764 SET_CX( context
, data
->FeatureBitsSwitches
);
766 case 0x20: /* ALTERNATE PRTSC */
767 FIXME("Install Alternate Print Screen - Not Supported\n");
769 case 0x30: /* SELECT VERTICAL RESOULTION */
770 FIXME("Select vertical resolution - not supported\n");
772 case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
773 FIXME("Default palette loading - not supported\n");
775 (data
->VGASettings
& 0xf7) |
776 ((AL_reg(context
) == 1) << 3);
778 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
779 FIXME("Video Addressing - Not Supported\n");
781 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
782 FIXME("Gray Scale Summing - Not Supported\n");
784 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
785 TRACE("Set cursor emulation to %d\n", AL_reg(context
));
787 (data
->ModeOptions
& 0xfe)|(AL_reg(context
) == 1);
789 case 0x36: /* VIDEO ADDRESS CONTROL */
790 FIXME("Video Address Control - Not Supported\n");
793 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
799 case 0x13: /* WRITE STRING */
800 /* This one does not imply that string be at cursor. */
801 FIXME("Write String - Not Supported\n");
805 switch AL_reg(context
) {
806 case 0x00: /* GET DISPLAY COMBINATION CODE */
807 TRACE("Get Display Combination Code\n");
808 SET_AX( context
, 0x001a );
809 SET_BL( context
, 0x08 ); /* VGA w/ color analog display */
810 SET_BH( context
, 0x00 ); /* No secondary hardware */
812 case 0x01: /* SET DISPLAY COMBINATION CODE */
813 FIXME("Set Display Combination Code - Not Supported\n");
816 FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
822 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
823 TRACE("Get functionality/state information\n");
824 if (BX_reg(context
) == 0x0)
826 SET_AL( context
, 0x1b );
827 /* Copy state information structure to ES:DI */
828 memcpy(CTX_SEG_OFF_TO_LIN(context
,context
->SegEs
,context
->Edi
),
829 &BIOS_EXTRA_PTR
->vid_state
,sizeof(VIDEOSTATE
));
833 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
834 FIXME("Save/Restore Video State - Not Supported\n");
837 case 0xef: /* get video mode for hercules-compatibles */
838 /* There's no reason to really support this */
839 /* is there?....................(A.C.) */
840 TRACE("Just report the video not hercules compatible\n");
841 SET_DX( context
, 0xffff );
844 case 0x4f: /* VESA */
845 DOSVM_Int10Handler_VESA(context
);
849 FIXME("Unknown - 0x%x\n", AH_reg(context
));
850 INT_BARF( context
, 0x10 );
854 static void scroll_window(int direction
, char lines
, char row1
,
855 char col1
, char row2
, char col2
, char attribute
)
857 if (!lines
) /* Actually, clear the window */
859 VGA_ClearText(row1
, col1
, row2
, col2
, attribute
);
861 else if (direction
== SCROLL_UP
)
863 VGA_ScrollUpText(row1
, col1
, row2
, col2
, lines
, attribute
);
867 VGA_ScrollDownText(row1
, col1
, row2
, col2
, lines
, attribute
);
871 /**********************************************************************
874 * Write single character to VGA console at the current
875 * cursor position and updates the BIOS cursor position.
877 void WINAPI
DOSVM_PutChar( BYTE ascii
)
879 BIOSDATA
*data
= BIOS_DATA
;
882 TRACE("char: 0x%02x(%c)\n", ascii
, ascii
);
884 DOSVM_InitializeVideoMode( data
);
886 VGA_PutChar( ascii
);
887 VGA_GetCursorPos( &xpos
, &ypos
);
888 BIOS_SetCursorPos( data
, 0, xpos
, ypos
);