Use correct linear pointer when accessing BIOS data area.
[wine/multimedia.git] / dlls / winedos / int10.c
blob410765b449efab50443412001aa8b320be59c656
1 /*
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
22 #include "config.h"
24 #include <stdlib.h>
26 #include "miscemu.h"
27 #include "vga.h"
28 #include "wine/debug.h"
29 #include "dosexe.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(int);
34 * Display combination code for active display.
36 * Values (hex):
37 * 00 - no display
38 * 01 - monochrome adapter w/ monochrome display
39 * 02 - CGA w/ color display
40 * 03 - reserved
41 * 04 - EGA w/ color display
42 * 05 - EGA w/ monochrome display
43 * 06 - PGA w/ color display
44 * 07 - VGA w/ monochrome analog display
45 * 08 - VGA w/ color analog display
46 * 09 - reserved
47 * 0A - MCGA w/ digital color display
48 * 0B - MCGA w/ monochrome analog display
49 * 0C - MCGA w/ color analog display
50 * FF - unknown display type
52 #define INT10_DCC 0x08
54 #include "pshpack1.h"
57 * Structure for DOS data that can be accessed directly from applications.
58 * This structure must be correctly packed.
60 typedef struct _INT10_HEAP {
61 BYTE StaticModeSupport[7]; /* modes supported 1..7 */
62 BYTE StaticScanlineSupport; /* scan lines supported */
63 BYTE StaticNumberCharBlocks; /* total number of char blocks */
64 BYTE StaticActiveCharBlocks; /* max number of active char blocks */
65 WORD StaticMiscFlags; /* misc function support flags */
66 WORD StaticReserved1; /* reserved */
67 BYTE StaticSavePointerFlags; /* save pointer function flags */
68 BYTE StaticReserved2; /* reserved */
70 WORD VesaCurrentMode;
71 WORD VesaModeList[64];
72 char VesaOEMName[32];
73 char VesaProductName[32];
74 char VesaProductRev[32];
75 char VesaVendorName[32];
77 WORD WineHeapSegment;
78 } INT10_HEAP;
80 #include "poppack.h"
83 * Wine internal information about video modes.
84 * If depth is zero, the mode is considered to
85 * be a text mode.
87 typedef struct {
88 WORD Mode;
89 WORD Width;
90 WORD Height;
91 WORD Depth;
92 } INT10_MODE;
96 * List of supported video modes.
98 static const INT10_MODE INT10_modelist[] =
100 {0x0000, 40, 25, 0},
101 {0x0001, 40, 25, 0},
102 {0x0002, 80, 25, 0},
103 {0x0003, 80, 25, 0},
104 {0x0007, 80, 25, 0},
105 {0x000d, 320, 200, 4},
106 {0x000e, 640, 200, 4},
107 {0x0010, 640, 350, 4},
108 {0x0012, 640, 480, 4},
109 {0x0013, 320, 200, 8},
110 {0x0100, 640, 400, 8},
111 {0x0101, 640, 480, 8},
112 {0x0102, 800, 600, 4},
113 {0x0103, 800, 600, 8},
114 {0x0104, 1024, 768, 4},
115 {0x0105, 1024, 768, 8},
116 {0x0106, 1280, 1024, 4},
117 {0x0107, 1280, 1024, 8},
118 {0x0108, 80, 60, 0},
119 {0x0109, 132, 25, 0},
120 {0x010a, 132, 43, 0},
121 {0x010b, 132, 50, 0},
122 {0x010c, 132, 60, 0},
123 {0x010d, 320, 200, 15},
124 {0x010e, 320, 200, 16},
125 {0x010f, 320, 200, 24},
126 {0x0110, 640, 480, 15},
127 {0x0111, 640, 480, 16},
128 {0x0112, 640, 480, 24},
129 {0x0113, 800, 600, 15},
130 {0x0114, 800, 600, 16},
131 {0x0115, 800, 600, 24},
132 {0x0116, 1024, 768, 15},
133 {0x0117, 1024, 768, 16},
134 {0x0118, 1024, 768, 24},
135 {0x0119, 1280, 1024, 15},
136 {0x011a, 1280, 1024, 16},
137 {0x011b, 1280, 1024, 24},
138 {0xffff, 0, 0, 0}
141 /* Forward declarations. */
142 static INT10_HEAP *INT10_GetHeap(void);
143 static void INT10_SetCursorPos(BIOSDATA*, unsigned, unsigned, unsigned);
146 /**********************************************************************
147 * INT10_FindMode
149 static const INT10_MODE *INT10_FindMode( WORD mode )
151 const INT10_MODE *ptr = INT10_modelist;
154 * Filter out flags.
156 mode &= 0x17f;
158 while (ptr->Mode != 0xffff)
160 if (ptr->Mode == mode)
161 return ptr;
162 ptr++;
165 return NULL;
169 /**********************************************************************
170 * INT10_FillControllerInformation
172 * Fill 256-byte (VBE1.x) or 512-byte buffer (VBE2.0+) with
173 * capabilities of the video controller.
175 static void INT10_FillControllerInformation( BYTE *buffer )
177 INT10_HEAP *heap = INT10_GetHeap();
179 /* 00 - BYTE[4]: signature */
180 memmove( buffer, "VESA", 4 );
182 /* 04 - WORD: version number */
183 *(WORD*)(buffer + 4) = 0x0300; /* version 3.0 */
185 /* 06 - DWORD: pointer to OEM name */
186 *(SEGPTR*)(buffer + 6) = MAKESEGPTR( heap->WineHeapSegment,
187 offsetof(INT10_HEAP,
188 VesaOEMName) );
191 * 10 - DWORD: capabilities flags
192 * Bits:
193 * 0 - DAC can be switched into 8-bit mode
194 * 1 - non-VGA controller
195 * 2 - programmed DAC with blank bit
196 * 3 - controller supports hardware stereoscopic signalling
197 * 4 - =0 stereo signalling via external VESA stereo connector
198 * =1 stereo signalling via VESA EVC connector
199 * 5 - controller supports hardware mouse cursor
200 * 6 - controller supports hardware clipping
201 * 7 - controller supports transparent BitBLT
202 * 8-31 - reserved (0)
204 *(DWORD*)(buffer + 10) = 0; /* FIXME */
206 /* 14 - DWORD: pointer to list of supported VESA and OEM video modes */
207 *(SEGPTR*)(buffer + 14) = MAKESEGPTR( heap->WineHeapSegment,
208 offsetof(INT10_HEAP,
209 VesaModeList) );
211 /* 18 - WORD: total amount of video memory in 64K blocks */
212 *(WORD*)(buffer + 18) = 16; /* FIXME */
214 /* 20 - WORD: OEM software version (BCD, high byte = major) */
215 *(WORD*)(buffer + 20) = 0x0100; /* version 1.0 */
217 /* 22 - DWORD: pointer to vendor name */
218 *(SEGPTR*)(buffer + 22) = MAKESEGPTR( heap->WineHeapSegment,
219 offsetof(INT10_HEAP,
220 VesaVendorName) );
222 /* 26 - DWORD: pointer to product name */
223 *(SEGPTR*)(buffer + 26) = MAKESEGPTR( heap->WineHeapSegment,
224 offsetof(INT10_HEAP,
225 VesaProductName) );
227 /* 30 - DWORD: pointer to product revision string */
228 *(SEGPTR*)(buffer + 30) = MAKESEGPTR( heap->WineHeapSegment,
229 offsetof(INT10_HEAP,
230 VesaProductRev) );
232 /* 34 - WORD: VBE/AF version (if capabilities bit 3 set) */
233 *(WORD*)(buffer + 34) = 0;
236 * 36 - DWORD: pointer to list of accelerated modes
237 * (if capabilities bit 3 set)
239 *(SEGPTR*)(buffer + 36) = 0;
241 /* 40 - BYTE[216]: reserved for VBE implementation, set to zero */
242 memset( buffer + 40, 216, 0 );
245 * 256 - BYTE[256]: reserved for VBE3.0 implementation,
246 * ignored in order to support older programs
251 /**********************************************************************
252 * INT10_FillModeInformation
254 * Fill 256-byte buffer with extended information about display mode.
256 * Returns FALSE if mode is unknown and TRUE is mode is known
257 * even if it is not supported.
259 static BOOL INT10_FillModeInformation( BYTE *buffer, WORD mode )
261 const INT10_MODE *ptr = INT10_FindMode( mode );
262 if (!ptr)
263 return FALSE;
266 * 00 - WORD: mode attributes
267 * Bits:
268 * 0 - Mode supported by present hardware configuration.
269 * 1 - Optional information available. Must be =1 for VBE v1.2+.
270 * 2 - BIOS output supported.
271 * Int10 functions 01, 02, 06, 07, 09, 0a and 0e are supported.
272 * 3 - Set if color, clear if monochrome.
273 * 4 - Set if graphics mode, clear if text mode.
274 * 5 - Mode is not VGA-compatible if set.
275 * VGA-compatible modes support standard VGA I/O ports.
276 * 6 - Bank-switched (or windowed) mode is not supported if set.
277 * 7 - Linear framebuffer mode supported.
278 * 8 - Double scanning supported.
279 * 9 - Interlaced operation supported.
280 * 10 - Triple buffering supported.
281 * 11 - Stereoscopic display supported.
282 * 12 - Dual display start address supported.
283 * 13-15 - Reserved.
286 WORD attr = 0x000a; /* color mode, optional info */
289 * FIXME: Attribute handling is incomplete.
292 /* Mode supported? FIXME: correct value */
293 attr |= 0x0001;
295 /* Graphical mode? */
296 if (ptr->Depth)
297 attr |= 0x0010;
299 /* Not VGA-compatible? */
300 if (mode > 0xff)
301 attr |= 0x0020;
303 *(WORD*)(buffer + 0) = attr;
307 * 02 - BYTE[2]: window attributes, window A and window B
308 * Bits:
309 * 0 - Window exists.
310 * 1 - Window is readable.
311 * 2 - Window is writable.
312 * 3-7 - Reserved.
314 buffer[2] = 0x07; /* window A exists, readable and writable */
315 buffer[3] = 0x00; /* window B not supported */
317 /* 04 - WORD: window granularity in KB */
318 *(WORD*)(buffer + 4) = 64;
320 /* 06 - WORD: window size in KB */
321 *(WORD*)(buffer + 6) = 64;
323 /* 08 - WORD[2]: start segments, window A and window B */
324 *(WORD*)(buffer + 8) = 0xa000; /* window A segment */
325 *(WORD*)(buffer + 10) = 0x0000; /* window B not supported */
327 /* 12 - DWORD: window positioning function */
328 *(DWORD*)(buffer + 12) = 0; /* not supported */
330 /* 16 - WORD: bytes per scan line */
331 *(WORD*)(buffer + 16) = 0; /* FIXME */
333 /* 18 - WORD: width in pixels (graphics) or characters (text) */
334 *(WORD*)(buffer + 18) = ptr->Width;
336 /* 20 - WORD: height in pixels (graphics) or characters (text) */
337 *(WORD*)(buffer + 20) = ptr->Height;
339 /* 22 - BYTE: width of character cell in pixels */
340 buffer[22] = 0; /* FIXME */
342 /* 23 - BYTE: height of character cell in pixels */
343 buffer[23] = 0; /* FIXME */
345 /* 24 - BYTE: number of memory planes */
346 buffer[24] = 1; /* FIXME */
348 /* 25 - BYTE: number of bits per pixel */
349 buffer[25] = ptr->Depth; /* FIXME: text modes? reserved bits? */
351 /* 26 - BYTE: number of banks */
352 buffer[26] = 1; /* FIXME */
355 * 27 - BYTE: memory model type
356 * Values (hex):
357 * 00 - Text mode
358 * 01 - CGA graphics
359 * 02 - Hercules graphics
360 * 03 - Planar
361 * 04 - Packed pixel
362 * 05 - Non-chain 4, 256 color
363 * 06 - Direct color
364 * 07 - YUV
365 * 08-0F - Reserved for VESA.
366 * 10-FF - OEM memory models.
368 if (!ptr->Depth)
369 buffer[27] = 0; /* text mode */
370 else
371 buffer[27] = 3; /* FIXME */
373 /* 28 - BYTE: size of bank in KB */
374 buffer[28] = 0; /* FIXME */
376 /* 29 - BYTE: number of image pages (less one) in video RAM */
377 buffer[29] = 0; /* FIXME */
379 /* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
380 buffer[30] = 0x01;
383 * 31 - BYTE: red mask size
384 * Size of red color component in bits.
385 * Used only when memory model is direct color, otherwise set to zero.
387 buffer[31] = 0; /* FIXME */
390 * 32 - BYTE: red field position
391 * Bit position of the least significant bit of red color component.
392 * Used only when memory model is direct color, otherwise set to zero.
394 buffer[32] = 0; /* FIXME */
396 /* 33 - BYTE: green mask size */
397 buffer[33] = 0; /* FIXME */
399 /* 34 - BYTE: green field position */
400 buffer[34] = 0; /* FIXME */
402 /* 35 - BYTE: blue mask size */
403 buffer[35] = 0; /* FIXME */
405 /* 36 - BYTE: blue field position */
406 buffer[36] = 0;
408 /* 37 - BYTE: reserved mask size */
409 buffer[37] = 0;
411 /* 38 - BYTE: reserved mask position */
412 buffer[38] = 0;
415 * 39 - BYTE: direct color mode info
416 * Bits:
417 * 0 - Set if color ramp is programmable.
418 * 1 - Set if bytes in reserved field may be used by application.
420 buffer[39] = 0; /* not supported */
422 /* 40 - DWORD: physical address of linear video buffer */
423 *(DWORD*)(buffer + 40) = 0; /* not supported */
425 /* 44 - DWORD: reserved, always zero */
426 *(DWORD*)(buffer + 44) = 0;
428 /* 48 - WORD: reserved, always zero */
429 *(WORD*)(buffer + 48) = 0;
431 /* 50 - WORD: bytes per scan line in linear modes */
432 *(WORD*)(buffer + 50) = *(WORD*)(buffer + 16);
434 /* 52 - BYTE: number of images (less one) for banked video modes */
435 buffer[52] = 0; /* FIXME */
437 /* 53 - BYTE: number of images (less one) for linear video modes */
438 buffer[53] = buffer[52];
440 /* 54 - BYTE: red mask size (linear modes) */
441 buffer[54] = buffer[31];
443 /* 55 - BYTE: red field position (linear modes) */
444 buffer[55] = buffer[32];
446 /* 56 - BYTE: green mask size (linear modes) */
447 buffer[56] = buffer[33];
449 /* 57 - BYTE: green field size (linear modes) */
450 buffer[57] = buffer[34];
452 /* 58 - BYTE: blue mask size (linear modes) */
453 buffer[58] = buffer[35];
455 /* 59 - BYTE: blue field position (linear modes) */
456 buffer[59] = buffer[36];
458 /* 60 - BYTE: reserved mask size (linear modes) */
459 buffer[60] = buffer[37];
461 /* 61 - BYTE: reserved mask position (linear modes) */
462 buffer[61] = buffer[38];
464 /* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
465 *(DWORD*)(buffer + 62) = 0; /* FIXME */
467 /* 66 - BYTE[190]: reserved, set to zero */
468 memset( buffer + 66, 190, 0 );
470 return TRUE;
474 /**********************************************************************
475 * INT10_FillStateInformation
477 * Fill 64-byte buffer with VGA state and functionality information.
479 static void INT10_FillStateInformation( BYTE *buffer, BIOSDATA *data )
481 INT10_HEAP *heap = INT10_GetHeap();
483 /* 00 - DWORD: address of static functionality table */
484 *(SEGPTR*)(buffer + 0) = MAKESEGPTR( heap->WineHeapSegment,
485 offsetof(INT10_HEAP,
486 StaticModeSupport) );
488 /* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
489 memmove( buffer + 4, &data->VideoMode, 30 );
491 /* 34 - BYTE: number of rows - 1 */
492 buffer[34] = data->RowsOnScreenMinus1;
494 /* 35 - WORD: bytes/character */
495 *(WORD*)(buffer + 35) = data->BytesPerChar;
497 /* 37 - BYTE: display combination code of active display */
498 buffer[37] = INT10_DCC;
500 /* 38 - BYTE: DCC of alternate display */
501 buffer[38] = 0; /* no secondary display */
503 /* 39 - WORD: number of colors supported in current mode (0000h = mono) */
504 *(WORD*)(buffer + 39) = 16; /* FIXME */
506 /* 41 - BYTE: number of pages supported in current mode */
507 buffer[41] = 1; /* FIXME */
510 * 42 - BYTE: number of scan lines active
511 * Values (hex):
512 * 00 = 200
513 * 01 = 350
514 * 02 = 400
515 * 03 = 480
517 buffer[42] = 3; /* FIXME */
519 /* 43 - BYTE: primary character block */
520 buffer[43] = 0; /* FIXME */
522 /* 44 - BYTE: secondary character block */
523 buffer[44] = 0; /* FIXME */
526 * 45 - BYTE: miscellaneous flags
527 * Bits:
528 * 0 - all modes on all displays on
529 * 1 - gray summing on
530 * 2 - monochrome display attached
531 * 3 - default palette loading disabled
532 * 4 - cursor emulation enabled
533 * 5 - 0 = intensity; 1 = blinking
534 * 6 - flat-panel display is active
535 * 7 - unused (0)
537 /* FIXME: Correct value? */
538 buffer[45] =
539 (data->VGASettings & 0x0f) |
540 ((data->ModeOptions & 1) << 4); /* cursor emulation */
543 * 46 - BYTE: non-VGA mode support
544 * Bits:
545 * 0 - BIOS supports information return for adapter interface
546 * 1 - adapter interface driver required
547 * 2 - 16-bit VGA graphics present
548 * 3 - =1 MFI attributes enabled
549 * =0 VGA attributes enabled
550 * 4 - 132-column mode supported
551 * 5-7 - reserved
553 buffer[46] = 0; /* FIXME: correct value? */
555 /* 47 - BYTE[2]: reserved, set to zero */
556 memset( buffer + 47, 2, 0 );
559 * 49 - BYTE: video memory available
560 * Values (hex):
561 * 00 - 64K
562 * 01 - 128K
563 * 02 - 192K
564 * 03 - 256K
566 buffer[49] = (data->ModeOptions & 0x60) >> 5; /* FIXME */
569 * 50 - BYTE: save pointer state flags
570 * Bits:
571 * 0 - 512 character set active
572 * 1 - dynamic save area present
573 * 2 - alpha font override active
574 * 3 - graphics font override active
575 * 4 - palette override active
576 * 5 - DCC override active
577 * 6-7 - unused (0)
579 buffer[50] = heap->StaticSavePointerFlags;
582 * 51 - BYTE: display information and status
583 * Bits:
584 * 0 - flat-panel display attached
585 * 1 - flat-panel display active
586 * 2 - color display
587 * 3-6 - reserved
588 * 7 - 640x480 flat-panel can be used simultaneously with CRT
590 buffer[51] = 4; /* FIXME: correct value? */
592 /* 52 - BYTE[12]: reserved, set to zero */
593 memset( buffer + 52, 12, 0 );
597 /**********************************************************************
598 * INT10_GetHeap
600 INT10_HEAP *INT10_GetHeap( void )
602 static INT10_HEAP *heap_pointer = 0;
604 if (!heap_pointer)
606 WORD segment;
607 int i;
609 heap_pointer = DOSVM_AllocDataUMB( sizeof(INT10_HEAP),
610 &segment,
611 0 );
613 for (i = 0; i < 7; i++)
614 heap_pointer->StaticModeSupport[i] = 0xff; /* FIXME */
616 heap_pointer->StaticScanlineSupport = 7; /* FIXME */
617 heap_pointer->StaticNumberCharBlocks = 0; /* FIXME */
618 heap_pointer->StaticActiveCharBlocks = 0; /* FIXME */
619 heap_pointer->StaticMiscFlags = 0x8ff; /* FIXME */
620 heap_pointer->StaticReserved1 = 0;
621 heap_pointer->StaticSavePointerFlags = 0x3f; /* FIXME */
622 heap_pointer->StaticReserved2 = 0;
624 for (i=0; TRUE; i++)
626 heap_pointer->VesaModeList[i] = INT10_modelist[i].Mode;
627 if (INT10_modelist[i].Mode == 0xffff)
628 break;
631 strcpy( heap_pointer->VesaOEMName, "WINE SVGA BOARD" );
632 strcpy( heap_pointer->VesaVendorName, "WINE" );
633 strcpy( heap_pointer->VesaProductName, "WINE SVGA" );
634 strcpy( heap_pointer->VesaProductRev, "2003" );
636 heap_pointer->VesaCurrentMode = 0; /* Initialized later. */
637 heap_pointer->WineHeapSegment = segment;
640 return heap_pointer;
644 /**********************************************************************
645 * INT10_SetVideoMode
647 * Change current video mode to any VGA or VESA mode.
648 * Returns TRUE if mode is supported.
650 * Mode bitfields:
651 * 0-6: .. Mode number (combined with bit 8).
652 * 7: =0 Clear screen.
653 * =1 Preserve display memory on mode change (VGA modes).
654 * 8: =0 VGA mode.
655 * =1 VESA mode.
656 * 9: .. Reserved, must be zero.
657 * 10: .. Reserved, must be zero.
658 * 11: =0 Use default refresh rate.
659 * =1 Use user specified refresh rate.
660 * 12: .. Reserved, must be zero.
661 * 13: .. Reserved, must be zero.
662 * 14: =0 Use windowed frame buffer model.
663 * =1 Use linear frame buffer model.
664 * 15: =0 Clear screen.
665 * =1 Preserve display memory on mode change (VESA modes).
667 static BOOL INT10_SetVideoMode( BIOSDATA *data, WORD mode )
669 const INT10_MODE *ptr = INT10_FindMode( mode );
670 INT10_HEAP *heap = INT10_GetHeap();
671 BOOL clearScreen = TRUE;
673 if (!ptr)
674 return FALSE;
677 * Linear framebuffer is not supported.
679 if (mode & 0x4000)
680 return FALSE;
683 * Check for VGA and VESA preserve video memory flag.
685 if ((mode & 0x0080) || (mode & 0x8000))
686 clearScreen = FALSE;
689 * Note that we do not mask out flags here on purpose.
691 heap->VesaCurrentMode = mode;
692 if (mode <= 0xff)
693 data->VideoMode = mode;
694 else
695 data->VideoMode = 0;
697 if (ptr->Depth == 0)
699 /* Text mode. */
700 TRACE( "Setting %s %dx%d text mode (screen %s)\n",
701 mode <= 0xff ? "VGA" : "VESA",
702 ptr->Width, ptr->Height,
703 clearScreen ? "cleared" : "preserved" );
706 * FIXME: We should check here if alpha mode could be set.
708 VGA_SetAlphaMode( ptr->Width, ptr->Height );
710 data->VideoColumns = ptr->Width;
711 data->RowsOnScreenMinus1 = ptr->Height - 1;
713 if (clearScreen)
715 VGA_ClearText( 0, 0, ptr->Height-1, ptr->Width-1, 0x07 );
716 INT10_SetCursorPos( data, 0, 0, 0 );
717 VGA_SetCursorPos( 0, 0 );
720 else
722 /* Graphics mode. */
723 TRACE( "Setting %s %dx%dx%d graphics mode (screen %s)\n",
724 mode <= 0xff ? "VGA" : "VESA",
725 ptr->Width, ptr->Height, ptr->Depth,
726 clearScreen ? "cleared" : "preserved" );
728 if (VGA_SetMode( ptr->Width, ptr->Height, ptr->Depth ))
729 return FALSE;
732 return TRUE;
736 /**********************************************************************
737 * INT10_GetCursorPos
739 static void INT10_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
741 *X = data->VideoCursorPos[page*2]; /* column */
742 *Y = data->VideoCursorPos[page*2+1]; /* row */
746 /**********************************************************************
747 * INT10_SetCursorPos
749 static void INT10_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
751 data->VideoCursorPos[page*2] = X;
752 data->VideoCursorPos[page*2+1] = Y;
756 /**********************************************************************
757 * INT10_InitializeVideoMode
759 * The first time this function is called VGA emulation is set to the
760 * default text mode.
762 static void INT10_InitializeVideoMode( BIOSDATA *data )
764 static BOOL already_initialized = FALSE;
765 unsigned width;
766 unsigned height;
768 if(already_initialized)
769 return;
770 already_initialized = TRUE;
772 VGA_InitAlphaMode(&width, &height);
775 * FIXME: Add more mappings between initial size and
776 * text modes.
778 if (width >= 80 && height >= 25)
779 INT10_SetVideoMode( data, 0x03 );
780 else
781 INT10_SetVideoMode( data, 0x01 );
785 /**********************************************************************
786 * INT10_HandleVESA
788 * Handler for VESA functions (int10 function 0x4f).
790 static void INT10_HandleVESA( CONTEXT86 *context )
792 BIOSDATA *data = DOSVM_BiosData();
794 switch(AL_reg(context)) {
796 case 0x00: /* RETURN CONTROLLER INFORMATION */
797 TRACE( "VESA RETURN CONTROLLER INFORMATION\n" );
799 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
800 context->SegEs,
801 context->Edi);
802 INT10_FillControllerInformation( ptr );
803 SET_AL( context, 0x4f );
804 SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
806 break;
808 case 0x01: /* RETURN MODE INFORMATION */
809 TRACE( "VESA RETURN MODE INFORMATION %04x\n", CX_reg(context) );
811 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
812 context->SegEs,
813 context->Edi);
814 SET_AL( context, 0x4f );
815 if (INT10_FillModeInformation( ptr, CX_reg(context) ))
816 SET_AH( context, 0x00 ); /* status: success */
817 else
818 SET_AH( context, 0x01 ); /* status: failed */
820 break;
822 case 0x02: /* SET SuperVGA VIDEO MODE */
823 TRACE( "Set VESA video mode %04x\n", BX_reg(context) );
824 SET_AL( context, 0x4f ); /* function supported */
825 if (INT10_SetVideoMode( data, BX_reg(context) ))
826 SET_AH( context, 0x00 ); /* success */
827 else
828 SET_AH( context, 0x01 ); /* failed */
829 break;
831 case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
832 SET_AL( context, 0x4f );
833 SET_AH( context, 0x00 );
834 SET_BX( context, INT10_GetHeap()->VesaCurrentMode );
835 break;
837 case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
838 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
839 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
840 /* maybe we should do this instead ? */
841 /* AH_reg(context = 0x01; not implemented so just fail */
842 break;
844 case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
846 * This subfunction supports only Window A (BL_reg == 0) and
847 * is assumes that window granularity is 64k.
849 switch(BH_reg(context)) {
850 case 0x00: /* select video memory window */
851 SET_AL( context, 0x4f ); /* function supported */
852 if(BL_reg(context) == 0) {
853 VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
854 SET_AH( context, 0x00 ); /* status: successful */
855 } else
856 SET_AH( context, 0x01 ); /* status: failed */
857 break;
858 case 0x01: /* get video memory window */
859 SET_AL( context, 0x4f ); /* function supported */
860 if(BL_reg(context) == 0) {
861 SET_DX( context, VGA_GetWindowStart() / 64 / 1024 );
862 SET_AH( context, 0x00 ); /* status: successful */
863 } else
864 SET_AH( context, 0x01 ); /* status: failed */
865 break;
866 default:
867 INT_BARF( context, 0x10 );
869 break;
871 case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
872 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
873 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
874 /* maybe we should do this instead ? */
875 /* AH_reg(context = 0x001; not implemented so just fail */
876 break;
878 case 0x07: /* GET/SET DISPLAY START */
879 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
880 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
881 /* maybe we should do this instead ? */
882 /* AH_reg(context = 0x001; not implemented so just fail */
883 break;
885 case 0x08: /* GET/SET DAC PALETTE CONTROL */
886 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
887 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
888 /* maybe we should do this instead ? */
889 /* AH_reg(context = 0x001; not implemented so just fail */
890 break;
892 case 0x09: /* SET PALETTE ENTRIES */
893 FIXME("VESA Set palette entries - not implemented\n");
894 break;
896 case 0x0a: /* GET PROTECTED-MODE CODE */
897 FIXME("VESA Get protected-mode code - not implemented\n");
898 break;
900 case 0x10: /* Display Power Management Extensions */
901 FIXME("VESA Display Power Management Extensions - not implemented\n");
902 break;
904 case 0xef: /* get video mode for hercules-compatibles */
905 /* There's no reason to really support this */
906 /* is there?....................(A.C.) */
907 TRACE("Just report the video not hercules compatible\n");
908 SET_DX( context, 0xffff );
909 break;
911 case 0xff: /* Turn VESA ON/OFF */
912 /* i dont know what to do */
913 break;
915 default:
916 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
917 break;
922 /**********************************************************************
923 * DOSVM_Int10Handler
925 * Handler for int 10h (video).
927 * NOTE:
928 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
929 * are present in this list. (SVGA and XGA are not) That is not
930 * to say that all these functions should be supported, but if
931 * anyone is brain-damaged enough to want to emulate one of these
932 * beasts then this should get you started.
934 * NOTE:
935 * Several common graphical extensions used by Microsoft hook
936 * off of here. I have *not* added them to this list (yet). They
937 * include:
939 * MSHERC.COM - More functionality for Hercules cards.
940 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
942 * Yes, MS also added this support into their mouse driver. Don't
943 * ask me, I don't work for them.
945 * Joseph Pranevich - 9/98
947 * Jess Haas 2/99
948 * Added support for Vesa. It is not complete but is a start.
949 * NOTE: Im not sure if i did all this right or if eny of it works.
950 * Currently i dont have a program that uses Vesa that actually gets far
951 * enough without crashing to do vesa stuff.
953 * Added additional vga graphic support - 3/99
955 void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
957 BIOSDATA *data = DOSVM_BiosData();
959 INT10_InitializeVideoMode( data );
961 switch(AH_reg(context)) {
963 case 0x00: /* SET VIDEO MODE */
964 TRACE( "Set VGA video mode %02x\n", AL_reg(context) );
965 if (!INT10_SetVideoMode( data, AL_reg(context) ))
966 FIXME( "Unsupported VGA video mode requested: %d\n",
967 AL_reg(context) );
968 break;
970 case 0x01: /* SET CURSOR SHAPE */
971 TRACE("Set Cursor Shape start %d end %d options %d\n",
972 CH_reg(context) & 0x1f,
973 CL_reg(context) & 0x1f,
974 CH_reg(context) & 0xe0);
975 data->VideoCursorType = CX_reg(context); /* direct copy */
976 VGA_SetCursorShape(CH_reg(context), CL_reg(context));
977 break;
979 case 0x02: /* SET CURSOR POSITION */
980 /* BH = Page Number */ /* Not supported */
981 /* DH = Row */ /* 0 is left */
982 /* DL = Column */ /* 0 is top */
983 INT10_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
984 if (BH_reg(context))
986 FIXME("Set Cursor Position: Cannot set to page %d\n",
987 BH_reg(context));
989 else
991 VGA_SetCursorPos(DL_reg(context), DH_reg(context));
992 TRACE("Set Cursor Position: %d/%d\n", DL_reg(context),
993 DH_reg(context));
995 break;
997 case 0x03: /* GET CURSOR POSITION AND SIZE */
999 unsigned row, col;
1001 TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
1002 SET_CX( context, data->VideoCursorType );
1003 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1004 SET_DH( context, row );
1005 SET_DL( context, col );
1006 TRACE("Cursor Position: %d/%d\n", DL_reg(context), DH_reg(context));
1008 break;
1010 case 0x04: /* READ LIGHT PEN POSITION */
1011 FIXME("Read Light Pen Position - Not Supported\n");
1012 SET_AH( context, 0x00 ); /* Not down */
1013 break;
1015 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
1016 FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context));
1017 data->VideoCurPage = AL_reg(context);
1018 break;
1020 case 0x06: /* SCROLL UP WINDOW */
1021 /* AL = Lines to scroll */
1022 /* BH = Attribute */
1023 /* CH,CL = row, col upper-left */
1024 /* DH,DL = row, col lower-right */
1025 TRACE("Scroll Up Window %d\n", AL_reg(context));
1027 if (AL_reg(context) == 0)
1028 VGA_ClearText( CH_reg(context), CL_reg(context),
1029 DH_reg(context), DL_reg(context),
1030 BH_reg(context) );
1031 else
1032 VGA_ScrollUpText( CH_reg(context), CL_reg(context),
1033 DH_reg(context), DL_reg(context),
1034 AL_reg(context), BH_reg(context) );
1035 break;
1037 case 0x07: /* SCROLL DOWN WINDOW */
1038 /* AL = Lines to scroll */
1039 /* BH = Attribute */
1040 /* CH,CL = row, col upper-left */
1041 /* DH,DL = row, col lower-right */
1042 TRACE("Scroll Down Window %d\n", AL_reg(context));
1044 if (AL_reg(context) == 0)
1045 VGA_ClearText( CH_reg(context), CL_reg(context),
1046 DH_reg(context), DL_reg(context),
1047 BH_reg(context) );
1048 else
1049 VGA_ScrollDownText( CH_reg(context), CL_reg(context),
1050 DH_reg(context), DL_reg(context),
1051 AL_reg(context), BH_reg(context) );
1052 break;
1054 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1056 if (BH_reg(context)) /* Write to different page */
1058 FIXME("Read character and attribute at cursor position -"
1059 " Can't read from non-0 page\n");
1060 SET_AL( context, ' ' ); /* That page is blank */
1061 SET_AH( context, 7 );
1063 else
1065 BYTE ascii, attr;
1066 TRACE("Read Character and Attribute at Cursor Position\n");
1067 VGA_GetCharacterAtCursor(&ascii, &attr);
1068 SET_AL( context, ascii );
1069 SET_AH( context, attr );
1072 break;
1074 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1075 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
1076 /* AL = Character to display. */
1077 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
1078 /* BL = Attribute / Color */
1079 /* CX = Times to Write Char */
1080 /* Note here that the cursor is not advanced. */
1082 unsigned row, col;
1084 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1085 VGA_WriteChars(col, row,
1086 AL_reg(context),
1087 (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
1088 CX_reg(context));
1089 if (CX_reg(context) > 1)
1090 TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
1091 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1092 CX_reg(context), AL_reg(context));
1093 else
1094 TRACE("Write Character%s at Cursor Position: %c\n",
1095 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1096 AL_reg(context));
1098 break;
1100 case 0x0b:
1101 switch BH_reg(context) {
1102 case 0x00: /* SET BACKGROUND/BORDER COLOR */
1103 /* In text modes, this sets only the border... */
1104 /* According to the interrupt list and one of my books. */
1105 /* Funny though that Beyond Zork seems to indicate that it
1106 also sets up the default background attributes for clears
1107 and scrolls... */
1108 /* Bear in mind here that we do not want to change,
1109 apparently, the foreground or attribute of the background
1110 with this call, so we should check first to see what the
1111 foreground already is... FIXME */
1112 FIXME("Set Background/Border Color: %d/%d\n",
1113 BH_reg(context), BL_reg(context));
1114 break;
1115 case 0x01: /* SET PALETTE */
1116 FIXME("Set Palette - Not Supported\n");
1117 break;
1118 default:
1119 FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
1120 BH_reg(context));
1121 break;
1123 break;
1125 case 0x0c: /* WRITE GRAPHICS PIXEL */
1126 /* Not in graphics mode, can ignore w/o error */
1127 FIXME("Write Graphics Pixel - Not Supported\n");
1128 break;
1130 case 0x0d: /* READ GRAPHICS PIXEL */
1131 /* Not in graphics mode, can ignore w/o error */
1132 FIXME("Read Graphics Pixel - Not Supported\n");
1133 break;
1135 case 0x0e: /* TELETYPE OUTPUT */
1136 TRACE("Teletype Output\n");
1137 DOSVM_PutChar(AL_reg(context));
1138 break;
1140 case 0x0f: /* GET CURRENT VIDEO MODE */
1141 TRACE("Get current video mode: -> mode %d, columns %d\n", data->VideoMode, data->VideoColumns);
1142 /* Note: This should not be a constant value. */
1143 SET_AL( context, data->VideoMode );
1144 SET_AH( context, data->VideoColumns );
1145 SET_BH( context, 0 ); /* Display page 0 */
1146 break;
1148 case 0x10:
1149 switch AL_reg(context) {
1150 case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
1151 TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
1152 BL_reg(context),BH_reg(context));
1153 /* BH is the value BL is the register */
1154 VGA_SetColor16((int)BL_reg(context),(int)BH_reg(context));
1155 break;
1156 case 0x01: /* SET BORDER (OVERSCAN) */
1157 /* Text terminals have no overscan */
1158 /* I'm setting it anyway. - A.C. */
1159 TRACE("Set Border (Overscan) - Ignored but set.\n");
1160 VGA_SetColor16(16,(int)BH_reg(context));
1161 break;
1162 case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
1163 TRACE("Set all palette registers\n");
1164 /* ES:DX points to a 17 byte table of colors */
1165 /* No return data listed */
1166 /* I'll have to update my table and the default palette */
1167 VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1168 break;
1169 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
1170 FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
1171 break;
1172 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
1173 TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context));
1174 /* BL is register to read [ 0-15 ] BH is return value */
1175 SET_BH( context, VGA_GetColor16((int)BL_reg(context)) );
1176 break;
1177 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
1178 TRACE("Read Overscan (Border Color) Register \n");
1179 SET_BH( context, VGA_GetColor16(16) );
1180 break;
1181 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
1182 TRACE("Read All Palette Registers and Overscan Register \n");
1183 /* ES:DX points to a 17 byte table where the results */
1184 /* of this call should be stored. */
1185 VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1186 break;
1187 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
1189 PALETTEENTRY paldat;
1191 TRACE("Set Individual DAC register\n");
1192 paldat.peRed = DH_reg(context);
1193 paldat.peGreen = CH_reg(context);
1194 paldat.peBlue = CL_reg(context);
1195 paldat.peFlags = 0;
1196 VGA_SetPalette(&paldat,BX_reg(context)&0xFF,1);
1198 break;
1199 case 0x12: /* SET BLOCK OF DAC REGISTERS */
1201 int i;
1202 PALETTEENTRY paldat;
1203 BYTE *pt;
1205 TRACE("Set Block of DAC registers\n");
1206 pt = (BYTE*)CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx);
1207 for (i=0;i<CX_reg(context);i++)
1209 paldat.peRed = (*(pt+i*3+0)) << 2;
1210 paldat.peGreen = (*(pt+i*3+1)) << 2;
1211 paldat.peBlue = (*(pt+i*3+2)) << 2;
1212 paldat.peFlags = 0;
1213 VGA_SetPalette(&paldat,(BX_reg(context)+i)&0xFF,1);
1216 break;
1217 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
1218 FIXME("Select video DAC color page - Not Supported\n");
1219 break;
1220 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
1221 FIXME("Read individual DAC register - Not Supported\n");
1222 break;
1223 case 0x17: /* READ BLOCK OF DAC REGISTERS */
1224 FIXME("Read block of DAC registers - Not Supported\n");
1225 break;
1226 case 0x18: /* SET PEL MASK */
1227 FIXME("Set PEL mask - Not Supported\n");
1228 break;
1229 case 0x19: /* READ PEL MASK */
1230 FIXME("Read PEL mask - Not Supported\n");
1231 break;
1232 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
1233 FIXME("Get video DAC color page state - Not Supported\n");
1234 break;
1235 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
1236 FIXME("Perform Gray-scale summing - Not Supported\n");
1237 break;
1238 default:
1239 FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
1240 AL_reg(context));
1241 break;
1243 break;
1245 case 0x11: /* TEXT MODE CHARGEN */
1246 /* Note that second subfunction is *almost* identical. */
1247 /* See INTERRUPT.A for details. */
1248 switch AL_reg(context) {
1249 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
1250 case 0x10:
1251 FIXME("Load User Specified Patterns - Not Supported\n");
1252 break;
1253 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
1254 case 0x11:
1255 FIXME("Load ROM Monochrome Patterns - Not Supported\n");
1256 break;
1257 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
1258 case 0x12:
1259 FIXME(
1260 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
1261 break;
1262 case 0x03: /* SET BLOCK SPECIFIER */
1263 FIXME("Set Block Specifier - Not Supported\n");
1264 break;
1265 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
1266 case 0x14:
1267 FIXME("Load ROM 8x16 Character Set - Not Supported\n");
1268 break;
1269 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
1270 FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
1271 break;
1272 case 0x21: /* SET USER GRAPICS CHARACTERS */
1273 FIXME("Set User Graphics Characters - Not Supported\n");
1274 break;
1275 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
1276 FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
1277 break;
1278 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
1279 FIXME(
1280 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
1281 break;
1282 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
1283 FIXME("Load 8x16 Graphic Chars - Not Supported\n");
1284 break;
1285 case 0x30: /* GET FONT INFORMATION */
1286 FIXME("Get Font Information - Not Supported\n");
1287 break;
1288 default:
1289 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1290 AL_reg(context));
1291 break;
1293 break;
1295 case 0x12: /* ALTERNATE FUNCTION SELECT */
1296 switch BL_reg(context) {
1297 case 0x10: /* GET EGA INFO */
1298 TRACE("EGA info requested\n");
1299 SET_BH( context, 0x00 ); /* Color screen */
1300 SET_BL( context, data->ModeOptions >> 5 ); /* EGA memory size */
1301 SET_CX( context, data->FeatureBitsSwitches );
1302 break;
1303 case 0x20: /* ALTERNATE PRTSC */
1304 FIXME("Install Alternate Print Screen - Not Supported\n");
1305 break;
1306 case 0x30: /* SELECT VERTICAL RESOULTION */
1307 FIXME("Select vertical resolution - not supported\n");
1308 break;
1309 case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
1310 FIXME("Default palette loading - not supported\n");
1311 data->VGASettings =
1312 (data->VGASettings & 0xf7) |
1313 ((AL_reg(context) == 1) << 3);
1314 break;
1315 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
1316 FIXME("Video Addressing - Not Supported\n");
1317 break;
1318 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
1319 FIXME("Gray Scale Summing - Not Supported\n");
1320 break;
1321 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
1322 TRACE("Set cursor emulation to %d\n", AL_reg(context));
1323 data->ModeOptions =
1324 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
1325 break;
1326 case 0x36: /* VIDEO ADDRESS CONTROL */
1327 FIXME("Video Address Control - Not Supported\n");
1328 break;
1329 default:
1330 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1331 AL_reg(context));
1332 break;
1334 break;
1336 case 0x13: /* WRITE STRING */
1337 /* This one does not imply that string be at cursor. */
1338 FIXME("Write String - Not Supported\n");
1339 break;
1341 case 0x1a:
1342 switch AL_reg(context) {
1343 case 0x00: /* GET DISPLAY COMBINATION CODE */
1344 TRACE("Get Display Combination Code\n");
1345 SET_AL( context, 0x1a ); /* Function supported */
1346 SET_BL( context, INT10_DCC ); /* Active display */
1347 SET_BH( context, 0x00 ); /* No alternate display */
1348 break;
1349 case 0x01: /* SET DISPLAY COMBINATION CODE */
1350 FIXME("Set Display Combination Code - Not Supported\n");
1351 break;
1352 default:
1353 FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
1354 AL_reg(context));
1355 break;
1357 break;
1359 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
1360 TRACE("Get functionality/state information\n");
1361 if (BX_reg(context) == 0x0000)
1363 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
1364 context->SegEs,
1365 context->Edi);
1366 SET_AL( context, 0x1b ); /* Function is supported */
1367 INT10_FillStateInformation( ptr, data );
1369 break;
1371 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
1372 FIXME("Save/Restore Video State - Not Supported\n");
1373 break;
1375 case 0xef: /* get video mode for hercules-compatibles */
1376 /* There's no reason to really support this */
1377 /* is there?....................(A.C.) */
1378 TRACE("Just report the video not hercules compatible\n");
1379 SET_DX( context, 0xffff );
1380 break;
1382 case 0x4f: /* VESA */
1383 INT10_HandleVESA(context);
1384 break;
1386 case 0xfe: /* GET SHADOW BUFFER */
1387 TRACE( "GET SHADOW BUFFER %lx:%x - ignored\n",
1388 context->SegEs, DI_reg(context) );
1389 break;
1391 default:
1392 FIXME("Unknown - 0x%x\n", AH_reg(context));
1393 INT_BARF( context, 0x10 );
1398 /**********************************************************************
1399 * DOSVM_PutChar
1401 * Write single character to VGA console at the current
1402 * cursor position and updates the BIOS cursor position.
1404 void WINAPI DOSVM_PutChar( BYTE ascii )
1406 BIOSDATA *data = DOSVM_BiosData();
1407 unsigned xpos, ypos;
1409 TRACE("char: 0x%02x(%c)\n", ascii, ascii);
1411 INT10_InitializeVideoMode( data );
1413 VGA_PutChar( ascii );
1414 VGA_GetCursorPos( &xpos, &ypos );
1415 INT10_SetCursorPos( data, 0, xpos, ypos );