Set the "bytes per scan line" field when generating the mode info
[wine/multimedia.git] / dlls / winedos / int10.c
blobb78acb347d1ed618e0bb266b4c9a8285c0911016
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 /* FIXME: is this always correct? */
332 *(WORD*)(buffer + 16) = ptr->Width * (ptr->Depth ? (ptr->Depth + 7) / 8 : 1);
334 /* 18 - WORD: width in pixels (graphics) or characters (text) */
335 *(WORD*)(buffer + 18) = ptr->Width;
337 /* 20 - WORD: height in pixels (graphics) or characters (text) */
338 *(WORD*)(buffer + 20) = ptr->Height;
340 /* 22 - BYTE: width of character cell in pixels */
341 buffer[22] = 0; /* FIXME */
343 /* 23 - BYTE: height of character cell in pixels */
344 buffer[23] = 0; /* FIXME */
346 /* 24 - BYTE: number of memory planes */
347 buffer[24] = 1; /* FIXME */
349 /* 25 - BYTE: number of bits per pixel */
350 buffer[25] = ptr->Depth; /* FIXME: text modes? reserved bits? */
352 /* 26 - BYTE: number of banks */
353 buffer[26] = 1; /* FIXME */
356 * 27 - BYTE: memory model type
357 * Values (hex):
358 * 00 - Text mode
359 * 01 - CGA graphics
360 * 02 - Hercules graphics
361 * 03 - Planar
362 * 04 - Packed pixel
363 * 05 - Non-chain 4, 256 color
364 * 06 - Direct color
365 * 07 - YUV
366 * 08-0F - Reserved for VESA.
367 * 10-FF - OEM memory models.
369 if (!ptr->Depth)
370 buffer[27] = 0; /* text mode */
371 else
372 buffer[27] = 3; /* FIXME */
374 /* 28 - BYTE: size of bank in KB */
375 buffer[28] = 0; /* FIXME */
377 /* 29 - BYTE: number of image pages (less one) in video RAM */
378 buffer[29] = 0; /* FIXME */
380 /* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
381 buffer[30] = 0x01;
384 * 31 - BYTE: red mask size
385 * Size of red color component in bits.
386 * Used only when memory model is direct color, otherwise set to zero.
388 buffer[31] = 0; /* FIXME */
391 * 32 - BYTE: red field position
392 * Bit position of the least significant bit of red color component.
393 * Used only when memory model is direct color, otherwise set to zero.
395 buffer[32] = 0; /* FIXME */
397 /* 33 - BYTE: green mask size */
398 buffer[33] = 0; /* FIXME */
400 /* 34 - BYTE: green field position */
401 buffer[34] = 0; /* FIXME */
403 /* 35 - BYTE: blue mask size */
404 buffer[35] = 0; /* FIXME */
406 /* 36 - BYTE: blue field position */
407 buffer[36] = 0;
409 /* 37 - BYTE: reserved mask size */
410 buffer[37] = 0;
412 /* 38 - BYTE: reserved mask position */
413 buffer[38] = 0;
416 * 39 - BYTE: direct color mode info
417 * Bits:
418 * 0 - Set if color ramp is programmable.
419 * 1 - Set if bytes in reserved field may be used by application.
421 buffer[39] = 0; /* not supported */
423 /* 40 - DWORD: physical address of linear video buffer */
424 *(DWORD*)(buffer + 40) = 0; /* not supported */
426 /* 44 - DWORD: reserved, always zero */
427 *(DWORD*)(buffer + 44) = 0;
429 /* 48 - WORD: reserved, always zero */
430 *(WORD*)(buffer + 48) = 0;
432 /* 50 - WORD: bytes per scan line in linear modes */
433 *(WORD*)(buffer + 50) = *(WORD*)(buffer + 16);
435 /* 52 - BYTE: number of images (less one) for banked video modes */
436 buffer[52] = 0; /* FIXME */
438 /* 53 - BYTE: number of images (less one) for linear video modes */
439 buffer[53] = buffer[52];
441 /* 54 - BYTE: red mask size (linear modes) */
442 buffer[54] = buffer[31];
444 /* 55 - BYTE: red field position (linear modes) */
445 buffer[55] = buffer[32];
447 /* 56 - BYTE: green mask size (linear modes) */
448 buffer[56] = buffer[33];
450 /* 57 - BYTE: green field size (linear modes) */
451 buffer[57] = buffer[34];
453 /* 58 - BYTE: blue mask size (linear modes) */
454 buffer[58] = buffer[35];
456 /* 59 - BYTE: blue field position (linear modes) */
457 buffer[59] = buffer[36];
459 /* 60 - BYTE: reserved mask size (linear modes) */
460 buffer[60] = buffer[37];
462 /* 61 - BYTE: reserved mask position (linear modes) */
463 buffer[61] = buffer[38];
465 /* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
466 *(DWORD*)(buffer + 62) = 0; /* FIXME */
468 /* 66 - BYTE[190]: reserved, set to zero */
469 memset( buffer + 66, 190, 0 );
471 return TRUE;
475 /**********************************************************************
476 * INT10_FillStateInformation
478 * Fill 64-byte buffer with VGA state and functionality information.
480 static void INT10_FillStateInformation( BYTE *buffer, BIOSDATA *data )
482 INT10_HEAP *heap = INT10_GetHeap();
484 /* 00 - DWORD: address of static functionality table */
485 *(SEGPTR*)(buffer + 0) = MAKESEGPTR( heap->WineHeapSegment,
486 offsetof(INT10_HEAP,
487 StaticModeSupport) );
489 /* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
490 memmove( buffer + 4, &data->VideoMode, 30 );
492 /* 34 - BYTE: number of rows - 1 */
493 buffer[34] = data->RowsOnScreenMinus1;
495 /* 35 - WORD: bytes/character */
496 *(WORD*)(buffer + 35) = data->BytesPerChar;
498 /* 37 - BYTE: display combination code of active display */
499 buffer[37] = INT10_DCC;
501 /* 38 - BYTE: DCC of alternate display */
502 buffer[38] = 0; /* no secondary display */
504 /* 39 - WORD: number of colors supported in current mode (0000h = mono) */
505 *(WORD*)(buffer + 39) = 16; /* FIXME */
507 /* 41 - BYTE: number of pages supported in current mode */
508 buffer[41] = 1; /* FIXME */
511 * 42 - BYTE: number of scan lines active
512 * Values (hex):
513 * 00 = 200
514 * 01 = 350
515 * 02 = 400
516 * 03 = 480
518 buffer[42] = 3; /* FIXME */
520 /* 43 - BYTE: primary character block */
521 buffer[43] = 0; /* FIXME */
523 /* 44 - BYTE: secondary character block */
524 buffer[44] = 0; /* FIXME */
527 * 45 - BYTE: miscellaneous flags
528 * Bits:
529 * 0 - all modes on all displays on
530 * 1 - gray summing on
531 * 2 - monochrome display attached
532 * 3 - default palette loading disabled
533 * 4 - cursor emulation enabled
534 * 5 - 0 = intensity; 1 = blinking
535 * 6 - flat-panel display is active
536 * 7 - unused (0)
538 /* FIXME: Correct value? */
539 buffer[45] =
540 (data->VGASettings & 0x0f) |
541 ((data->ModeOptions & 1) << 4); /* cursor emulation */
544 * 46 - BYTE: non-VGA mode support
545 * Bits:
546 * 0 - BIOS supports information return for adapter interface
547 * 1 - adapter interface driver required
548 * 2 - 16-bit VGA graphics present
549 * 3 - =1 MFI attributes enabled
550 * =0 VGA attributes enabled
551 * 4 - 132-column mode supported
552 * 5-7 - reserved
554 buffer[46] = 0; /* FIXME: correct value? */
556 /* 47 - BYTE[2]: reserved, set to zero */
557 memset( buffer + 47, 2, 0 );
560 * 49 - BYTE: video memory available
561 * Values (hex):
562 * 00 - 64K
563 * 01 - 128K
564 * 02 - 192K
565 * 03 - 256K
567 buffer[49] = (data->ModeOptions & 0x60) >> 5; /* FIXME */
570 * 50 - BYTE: save pointer state flags
571 * Bits:
572 * 0 - 512 character set active
573 * 1 - dynamic save area present
574 * 2 - alpha font override active
575 * 3 - graphics font override active
576 * 4 - palette override active
577 * 5 - DCC override active
578 * 6-7 - unused (0)
580 buffer[50] = heap->StaticSavePointerFlags;
583 * 51 - BYTE: display information and status
584 * Bits:
585 * 0 - flat-panel display attached
586 * 1 - flat-panel display active
587 * 2 - color display
588 * 3-6 - reserved
589 * 7 - 640x480 flat-panel can be used simultaneously with CRT
591 buffer[51] = 4; /* FIXME: correct value? */
593 /* 52 - BYTE[12]: reserved, set to zero */
594 memset( buffer + 52, 12, 0 );
598 /**********************************************************************
599 * INT10_GetHeap
601 INT10_HEAP *INT10_GetHeap( void )
603 static INT10_HEAP *heap_pointer = 0;
605 if (!heap_pointer)
607 WORD segment;
608 int i;
610 heap_pointer = DOSVM_AllocDataUMB( sizeof(INT10_HEAP),
611 &segment,
612 0 );
614 for (i = 0; i < 7; i++)
615 heap_pointer->StaticModeSupport[i] = 0xff; /* FIXME */
617 heap_pointer->StaticScanlineSupport = 7; /* FIXME */
618 heap_pointer->StaticNumberCharBlocks = 0; /* FIXME */
619 heap_pointer->StaticActiveCharBlocks = 0; /* FIXME */
620 heap_pointer->StaticMiscFlags = 0x8ff; /* FIXME */
621 heap_pointer->StaticReserved1 = 0;
622 heap_pointer->StaticSavePointerFlags = 0x3f; /* FIXME */
623 heap_pointer->StaticReserved2 = 0;
625 for (i=0; TRUE; i++)
627 heap_pointer->VesaModeList[i] = INT10_modelist[i].Mode;
628 if (INT10_modelist[i].Mode == 0xffff)
629 break;
632 strcpy( heap_pointer->VesaOEMName, "WINE SVGA BOARD" );
633 strcpy( heap_pointer->VesaVendorName, "WINE" );
634 strcpy( heap_pointer->VesaProductName, "WINE SVGA" );
635 strcpy( heap_pointer->VesaProductRev, "2003" );
637 heap_pointer->VesaCurrentMode = 0; /* Initialized later. */
638 heap_pointer->WineHeapSegment = segment;
641 return heap_pointer;
645 /**********************************************************************
646 * INT10_SetVideoMode
648 * Change current video mode to any VGA or VESA mode.
649 * Returns TRUE if mode is supported.
651 * Mode bitfields:
652 * 0-6: .. Mode number (combined with bit 8).
653 * 7: =0 Clear screen.
654 * =1 Preserve display memory on mode change (VGA modes).
655 * 8: =0 VGA mode.
656 * =1 VESA mode.
657 * 9: .. Reserved, must be zero.
658 * 10: .. Reserved, must be zero.
659 * 11: =0 Use default refresh rate.
660 * =1 Use user specified refresh rate.
661 * 12: .. Reserved, must be zero.
662 * 13: .. Reserved, must be zero.
663 * 14: =0 Use windowed frame buffer model.
664 * =1 Use linear frame buffer model.
665 * 15: =0 Clear screen.
666 * =1 Preserve display memory on mode change (VESA modes).
668 static BOOL INT10_SetVideoMode( BIOSDATA *data, WORD mode )
670 const INT10_MODE *ptr = INT10_FindMode( mode );
671 INT10_HEAP *heap = INT10_GetHeap();
672 BOOL clearScreen = TRUE;
674 if (!ptr)
675 return FALSE;
678 * Linear framebuffer is not supported.
680 if (mode & 0x4000)
681 return FALSE;
684 * Check for VGA and VESA preserve video memory flag.
686 if ((mode & 0x0080) || (mode & 0x8000))
687 clearScreen = FALSE;
690 * Note that we do not mask out flags here on purpose.
692 heap->VesaCurrentMode = mode;
693 if (mode <= 0xff)
694 data->VideoMode = mode;
695 else
696 data->VideoMode = 0;
698 if (ptr->Depth == 0)
700 /* Text mode. */
701 TRACE( "Setting %s %dx%d text mode (screen %s)\n",
702 mode <= 0xff ? "VGA" : "VESA",
703 ptr->Width, ptr->Height,
704 clearScreen ? "cleared" : "preserved" );
707 * FIXME: We should check here if alpha mode could be set.
709 VGA_SetAlphaMode( ptr->Width, ptr->Height );
711 data->VideoColumns = ptr->Width;
712 data->RowsOnScreenMinus1 = ptr->Height - 1;
714 if (clearScreen)
716 VGA_ClearText( 0, 0, ptr->Height-1, ptr->Width-1, 0x07 );
717 INT10_SetCursorPos( data, 0, 0, 0 );
718 VGA_SetCursorPos( 0, 0 );
721 else
723 /* Graphics mode. */
724 TRACE( "Setting %s %dx%dx%d graphics mode (screen %s)\n",
725 mode <= 0xff ? "VGA" : "VESA",
726 ptr->Width, ptr->Height, ptr->Depth,
727 clearScreen ? "cleared" : "preserved" );
729 if (VGA_SetMode( ptr->Width, ptr->Height, ptr->Depth ))
730 return FALSE;
733 return TRUE;
737 /**********************************************************************
738 * INT10_GetCursorPos
740 static void INT10_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
742 *X = data->VideoCursorPos[page*2]; /* column */
743 *Y = data->VideoCursorPos[page*2+1]; /* row */
747 /**********************************************************************
748 * INT10_SetCursorPos
750 static void INT10_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
752 data->VideoCursorPos[page*2] = X;
753 data->VideoCursorPos[page*2+1] = Y;
757 /**********************************************************************
758 * INT10_InitializeVideoMode
760 * The first time this function is called VGA emulation is set to the
761 * default text mode.
763 static void INT10_InitializeVideoMode( BIOSDATA *data )
765 static BOOL already_initialized = FALSE;
766 unsigned width;
767 unsigned height;
769 if(already_initialized)
770 return;
771 already_initialized = TRUE;
773 VGA_InitAlphaMode(&width, &height);
776 * FIXME: Add more mappings between initial size and
777 * text modes.
779 if (width >= 80 && height >= 25)
780 INT10_SetVideoMode( data, 0x03 );
781 else
782 INT10_SetVideoMode( data, 0x01 );
786 /**********************************************************************
787 * INT10_HandleVESA
789 * Handler for VESA functions (int10 function 0x4f).
791 static void INT10_HandleVESA( CONTEXT86 *context )
793 BIOSDATA *data = DOSVM_BiosData();
795 switch(AL_reg(context)) {
797 case 0x00: /* RETURN CONTROLLER INFORMATION */
798 TRACE( "VESA RETURN CONTROLLER INFORMATION\n" );
800 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
801 context->SegEs,
802 context->Edi);
803 INT10_FillControllerInformation( ptr );
804 SET_AL( context, 0x4f );
805 SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
807 break;
809 case 0x01: /* RETURN MODE INFORMATION */
810 TRACE( "VESA RETURN MODE INFORMATION %04x\n", CX_reg(context) );
812 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
813 context->SegEs,
814 context->Edi);
815 SET_AL( context, 0x4f );
816 if (INT10_FillModeInformation( ptr, CX_reg(context) ))
817 SET_AH( context, 0x00 ); /* status: success */
818 else
819 SET_AH( context, 0x01 ); /* status: failed */
821 break;
823 case 0x02: /* SET SuperVGA VIDEO MODE */
824 TRACE( "Set VESA video mode %04x\n", BX_reg(context) );
825 SET_AL( context, 0x4f ); /* function supported */
826 if (INT10_SetVideoMode( data, BX_reg(context) ))
827 SET_AH( context, 0x00 ); /* success */
828 else
829 SET_AH( context, 0x01 ); /* failed */
830 break;
832 case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
833 SET_AL( context, 0x4f );
834 SET_AH( context, 0x00 );
835 SET_BX( context, INT10_GetHeap()->VesaCurrentMode );
836 break;
838 case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
839 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
840 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
841 /* maybe we should do this instead ? */
842 /* AH_reg(context = 0x01; not implemented so just fail */
843 break;
845 case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
847 * This subfunction supports only Window A (BL_reg == 0) and
848 * is assumes that window granularity is 64k.
850 switch(BH_reg(context)) {
851 case 0x00: /* select video memory window */
852 SET_AL( context, 0x4f ); /* function supported */
853 if(BL_reg(context) == 0) {
854 VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
855 SET_AH( context, 0x00 ); /* status: successful */
856 } else
857 SET_AH( context, 0x01 ); /* status: failed */
858 break;
859 case 0x01: /* get video memory window */
860 SET_AL( context, 0x4f ); /* function supported */
861 if(BL_reg(context) == 0) {
862 SET_DX( context, VGA_GetWindowStart() / 64 / 1024 );
863 SET_AH( context, 0x00 ); /* status: successful */
864 } else
865 SET_AH( context, 0x01 ); /* status: failed */
866 break;
867 default:
868 INT_BARF( context, 0x10 );
870 break;
872 case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
873 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
874 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
875 /* maybe we should do this instead ? */
876 /* AH_reg(context = 0x001; not implemented so just fail */
877 break;
879 case 0x07: /* GET/SET DISPLAY START */
880 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
881 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
882 /* maybe we should do this instead ? */
883 /* AH_reg(context = 0x001; not implemented so just fail */
884 break;
886 case 0x08: /* GET/SET DAC PALETTE CONTROL */
887 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
888 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
889 /* maybe we should do this instead ? */
890 /* AH_reg(context = 0x001; not implemented so just fail */
891 break;
893 case 0x09: /* SET PALETTE ENTRIES */
894 FIXME("VESA Set palette entries - not implemented\n");
895 break;
897 case 0x0a: /* GET PROTECTED-MODE CODE */
898 FIXME("VESA Get protected-mode code - not implemented\n");
899 break;
901 case 0x10: /* Display Power Management Extensions */
902 FIXME("VESA Display Power Management Extensions - not implemented\n");
903 break;
905 case 0xef: /* get video mode for hercules-compatibles */
906 /* There's no reason to really support this */
907 /* is there?....................(A.C.) */
908 TRACE("Just report the video not hercules compatible\n");
909 SET_DX( context, 0xffff );
910 break;
912 case 0xff: /* Turn VESA ON/OFF */
913 /* i dont know what to do */
914 break;
916 default:
917 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
918 break;
923 /**********************************************************************
924 * DOSVM_Int10Handler
926 * Handler for int 10h (video).
928 * NOTE:
929 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
930 * are present in this list. (SVGA and XGA are not) That is not
931 * to say that all these functions should be supported, but if
932 * anyone is brain-damaged enough to want to emulate one of these
933 * beasts then this should get you started.
935 * NOTE:
936 * Several common graphical extensions used by Microsoft hook
937 * off of here. I have *not* added them to this list (yet). They
938 * include:
940 * MSHERC.COM - More functionality for Hercules cards.
941 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
943 * Yes, MS also added this support into their mouse driver. Don't
944 * ask me, I don't work for them.
946 * Joseph Pranevich - 9/98
948 * Jess Haas 2/99
949 * Added support for Vesa. It is not complete but is a start.
950 * NOTE: Im not sure if i did all this right or if eny of it works.
951 * Currently i dont have a program that uses Vesa that actually gets far
952 * enough without crashing to do vesa stuff.
954 * Added additional vga graphic support - 3/99
956 void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
958 BIOSDATA *data = DOSVM_BiosData();
960 INT10_InitializeVideoMode( data );
962 switch(AH_reg(context)) {
964 case 0x00: /* SET VIDEO MODE */
965 TRACE( "Set VGA video mode %02x\n", AL_reg(context) );
966 if (!INT10_SetVideoMode( data, AL_reg(context) ))
967 FIXME( "Unsupported VGA video mode requested: %d\n",
968 AL_reg(context) );
969 break;
971 case 0x01: /* SET CURSOR SHAPE */
972 TRACE("Set Cursor Shape start %d end %d options %d\n",
973 CH_reg(context) & 0x1f,
974 CL_reg(context) & 0x1f,
975 CH_reg(context) & 0xe0);
976 data->VideoCursorType = CX_reg(context); /* direct copy */
977 VGA_SetCursorShape(CH_reg(context), CL_reg(context));
978 break;
980 case 0x02: /* SET CURSOR POSITION */
981 /* BH = Page Number */ /* Not supported */
982 /* DH = Row */ /* 0 is left */
983 /* DL = Column */ /* 0 is top */
984 INT10_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
985 if (BH_reg(context))
987 FIXME("Set Cursor Position: Cannot set to page %d\n",
988 BH_reg(context));
990 else
992 VGA_SetCursorPos(DL_reg(context), DH_reg(context));
993 TRACE("Set Cursor Position: %d/%d\n", DL_reg(context),
994 DH_reg(context));
996 break;
998 case 0x03: /* GET CURSOR POSITION AND SIZE */
1000 unsigned row, col;
1002 TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
1003 SET_CX( context, data->VideoCursorType );
1004 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1005 SET_DH( context, row );
1006 SET_DL( context, col );
1007 TRACE("Cursor Position: %d/%d\n", DL_reg(context), DH_reg(context));
1009 break;
1011 case 0x04: /* READ LIGHT PEN POSITION */
1012 FIXME("Read Light Pen Position - Not Supported\n");
1013 SET_AH( context, 0x00 ); /* Not down */
1014 break;
1016 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
1017 FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context));
1018 data->VideoCurPage = AL_reg(context);
1019 break;
1021 case 0x06: /* SCROLL UP WINDOW */
1022 /* AL = Lines to scroll */
1023 /* BH = Attribute */
1024 /* CH,CL = row, col upper-left */
1025 /* DH,DL = row, col lower-right */
1026 TRACE("Scroll Up Window %d\n", AL_reg(context));
1028 if (AL_reg(context) == 0)
1029 VGA_ClearText( CH_reg(context), CL_reg(context),
1030 DH_reg(context), DL_reg(context),
1031 BH_reg(context) );
1032 else
1033 VGA_ScrollUpText( CH_reg(context), CL_reg(context),
1034 DH_reg(context), DL_reg(context),
1035 AL_reg(context), BH_reg(context) );
1036 break;
1038 case 0x07: /* SCROLL DOWN WINDOW */
1039 /* AL = Lines to scroll */
1040 /* BH = Attribute */
1041 /* CH,CL = row, col upper-left */
1042 /* DH,DL = row, col lower-right */
1043 TRACE("Scroll Down Window %d\n", AL_reg(context));
1045 if (AL_reg(context) == 0)
1046 VGA_ClearText( CH_reg(context), CL_reg(context),
1047 DH_reg(context), DL_reg(context),
1048 BH_reg(context) );
1049 else
1050 VGA_ScrollDownText( CH_reg(context), CL_reg(context),
1051 DH_reg(context), DL_reg(context),
1052 AL_reg(context), BH_reg(context) );
1053 break;
1055 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1057 if (BH_reg(context)) /* Write to different page */
1059 FIXME("Read character and attribute at cursor position -"
1060 " Can't read from non-0 page\n");
1061 SET_AL( context, ' ' ); /* That page is blank */
1062 SET_AH( context, 7 );
1064 else
1066 BYTE ascii, attr;
1067 TRACE("Read Character and Attribute at Cursor Position\n");
1068 VGA_GetCharacterAtCursor(&ascii, &attr);
1069 SET_AL( context, ascii );
1070 SET_AH( context, attr );
1073 break;
1075 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1076 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
1077 /* AL = Character to display. */
1078 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
1079 /* BL = Attribute / Color */
1080 /* CX = Times to Write Char */
1081 /* Note here that the cursor is not advanced. */
1083 unsigned row, col;
1085 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1086 VGA_WriteChars(col, row,
1087 AL_reg(context),
1088 (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
1089 CX_reg(context));
1090 if (CX_reg(context) > 1)
1091 TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
1092 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1093 CX_reg(context), AL_reg(context));
1094 else
1095 TRACE("Write Character%s at Cursor Position: %c\n",
1096 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1097 AL_reg(context));
1099 break;
1101 case 0x0b:
1102 switch BH_reg(context) {
1103 case 0x00: /* SET BACKGROUND/BORDER COLOR */
1104 /* In text modes, this sets only the border... */
1105 /* According to the interrupt list and one of my books. */
1106 /* Funny though that Beyond Zork seems to indicate that it
1107 also sets up the default background attributes for clears
1108 and scrolls... */
1109 /* Bear in mind here that we do not want to change,
1110 apparently, the foreground or attribute of the background
1111 with this call, so we should check first to see what the
1112 foreground already is... FIXME */
1113 FIXME("Set Background/Border Color: %d/%d\n",
1114 BH_reg(context), BL_reg(context));
1115 break;
1116 case 0x01: /* SET PALETTE */
1117 FIXME("Set Palette - Not Supported\n");
1118 break;
1119 default:
1120 FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
1121 BH_reg(context));
1122 break;
1124 break;
1126 case 0x0c: /* WRITE GRAPHICS PIXEL */
1127 /* Not in graphics mode, can ignore w/o error */
1128 FIXME("Write Graphics Pixel - Not Supported\n");
1129 break;
1131 case 0x0d: /* READ GRAPHICS PIXEL */
1132 /* Not in graphics mode, can ignore w/o error */
1133 FIXME("Read Graphics Pixel - Not Supported\n");
1134 break;
1136 case 0x0e: /* TELETYPE OUTPUT */
1137 TRACE("Teletype Output\n");
1138 DOSVM_PutChar(AL_reg(context));
1139 break;
1141 case 0x0f: /* GET CURRENT VIDEO MODE */
1142 TRACE("Get current video mode: -> mode %d, columns %d\n", data->VideoMode, data->VideoColumns);
1143 /* Note: This should not be a constant value. */
1144 SET_AL( context, data->VideoMode );
1145 SET_AH( context, data->VideoColumns );
1146 SET_BH( context, 0 ); /* Display page 0 */
1147 break;
1149 case 0x10:
1150 switch AL_reg(context) {
1151 case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
1152 TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
1153 BL_reg(context),BH_reg(context));
1154 /* BH is the value BL is the register */
1155 VGA_SetColor16((int)BL_reg(context),(int)BH_reg(context));
1156 break;
1157 case 0x01: /* SET BORDER (OVERSCAN) */
1158 /* Text terminals have no overscan */
1159 /* I'm setting it anyway. - A.C. */
1160 TRACE("Set Border (Overscan) - Ignored but set.\n");
1161 VGA_SetColor16(16,(int)BH_reg(context));
1162 break;
1163 case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
1164 TRACE("Set all palette registers\n");
1165 /* ES:DX points to a 17 byte table of colors */
1166 /* No return data listed */
1167 /* I'll have to update my table and the default palette */
1168 VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1169 break;
1170 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
1171 FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
1172 break;
1173 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
1174 TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context));
1175 /* BL is register to read [ 0-15 ] BH is return value */
1176 SET_BH( context, VGA_GetColor16((int)BL_reg(context)) );
1177 break;
1178 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
1179 TRACE("Read Overscan (Border Color) Register \n");
1180 SET_BH( context, VGA_GetColor16(16) );
1181 break;
1182 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
1183 TRACE("Read All Palette Registers and Overscan Register \n");
1184 /* ES:DX points to a 17 byte table where the results */
1185 /* of this call should be stored. */
1186 VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1187 break;
1188 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
1190 PALETTEENTRY paldat;
1192 TRACE("Set Individual DAC register\n");
1193 paldat.peRed = DH_reg(context);
1194 paldat.peGreen = CH_reg(context);
1195 paldat.peBlue = CL_reg(context);
1196 paldat.peFlags = 0;
1197 VGA_SetPalette(&paldat,BX_reg(context)&0xFF,1);
1199 break;
1200 case 0x12: /* SET BLOCK OF DAC REGISTERS */
1202 int i;
1203 PALETTEENTRY paldat;
1204 BYTE *pt;
1206 TRACE("Set Block of DAC registers\n");
1207 pt = (BYTE*)CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx);
1208 for (i=0;i<CX_reg(context);i++)
1210 paldat.peRed = (*(pt+i*3+0)) << 2;
1211 paldat.peGreen = (*(pt+i*3+1)) << 2;
1212 paldat.peBlue = (*(pt+i*3+2)) << 2;
1213 paldat.peFlags = 0;
1214 VGA_SetPalette(&paldat,(BX_reg(context)+i)&0xFF,1);
1217 break;
1218 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
1219 FIXME("Select video DAC color page - Not Supported\n");
1220 break;
1221 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
1222 FIXME("Read individual DAC register - Not Supported\n");
1223 break;
1224 case 0x17: /* READ BLOCK OF DAC REGISTERS */
1225 FIXME("Read block of DAC registers - Not Supported\n");
1226 break;
1227 case 0x18: /* SET PEL MASK */
1228 FIXME("Set PEL mask - Not Supported\n");
1229 break;
1230 case 0x19: /* READ PEL MASK */
1231 FIXME("Read PEL mask - Not Supported\n");
1232 break;
1233 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
1234 FIXME("Get video DAC color page state - Not Supported\n");
1235 break;
1236 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
1237 FIXME("Perform Gray-scale summing - Not Supported\n");
1238 break;
1239 default:
1240 FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
1241 AL_reg(context));
1242 break;
1244 break;
1246 case 0x11: /* TEXT MODE CHARGEN */
1247 /* Note that second subfunction is *almost* identical. */
1248 /* See INTERRUPT.A for details. */
1249 switch AL_reg(context) {
1250 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
1251 case 0x10:
1252 FIXME("Load User Specified Patterns - Not Supported\n");
1253 break;
1254 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
1255 case 0x11:
1256 FIXME("Load ROM Monochrome Patterns - Not Supported\n");
1257 break;
1258 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
1259 case 0x12:
1260 FIXME(
1261 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
1262 break;
1263 case 0x03: /* SET BLOCK SPECIFIER */
1264 FIXME("Set Block Specifier - Not Supported\n");
1265 break;
1266 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
1267 case 0x14:
1268 FIXME("Load ROM 8x16 Character Set - Not Supported\n");
1269 break;
1270 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
1271 FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
1272 break;
1273 case 0x21: /* SET USER GRAPICS CHARACTERS */
1274 FIXME("Set User Graphics Characters - Not Supported\n");
1275 break;
1276 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
1277 FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
1278 break;
1279 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
1280 FIXME(
1281 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
1282 break;
1283 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
1284 FIXME("Load 8x16 Graphic Chars - Not Supported\n");
1285 break;
1286 case 0x30: /* GET FONT INFORMATION */
1287 FIXME("Get Font Information - Not Supported\n");
1288 break;
1289 default:
1290 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1291 AL_reg(context));
1292 break;
1294 break;
1296 case 0x12: /* ALTERNATE FUNCTION SELECT */
1297 switch BL_reg(context) {
1298 case 0x10: /* GET EGA INFO */
1299 TRACE("EGA info requested\n");
1300 SET_BH( context, 0x00 ); /* Color screen */
1301 SET_BL( context, data->ModeOptions >> 5 ); /* EGA memory size */
1302 SET_CX( context, data->FeatureBitsSwitches );
1303 break;
1304 case 0x20: /* ALTERNATE PRTSC */
1305 FIXME("Install Alternate Print Screen - Not Supported\n");
1306 break;
1307 case 0x30: /* SELECT VERTICAL RESOULTION */
1308 FIXME("Select vertical resolution - not supported\n");
1309 break;
1310 case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
1311 FIXME("Default palette loading - not supported\n");
1312 data->VGASettings =
1313 (data->VGASettings & 0xf7) |
1314 ((AL_reg(context) == 1) << 3);
1315 break;
1316 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
1317 FIXME("Video Addressing - Not Supported\n");
1318 break;
1319 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
1320 FIXME("Gray Scale Summing - Not Supported\n");
1321 break;
1322 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
1323 TRACE("Set cursor emulation to %d\n", AL_reg(context));
1324 data->ModeOptions =
1325 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
1326 break;
1327 case 0x36: /* VIDEO ADDRESS CONTROL */
1328 FIXME("Video Address Control - Not Supported\n");
1329 break;
1330 default:
1331 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1332 AL_reg(context));
1333 break;
1335 break;
1337 case 0x13: /* WRITE STRING */
1338 /* This one does not imply that string be at cursor. */
1339 FIXME("Write String - Not Supported\n");
1340 break;
1342 case 0x1a:
1343 switch AL_reg(context) {
1344 case 0x00: /* GET DISPLAY COMBINATION CODE */
1345 TRACE("Get Display Combination Code\n");
1346 SET_AL( context, 0x1a ); /* Function supported */
1347 SET_BL( context, INT10_DCC ); /* Active display */
1348 SET_BH( context, 0x00 ); /* No alternate display */
1349 break;
1350 case 0x01: /* SET DISPLAY COMBINATION CODE */
1351 FIXME("Set Display Combination Code - Not Supported\n");
1352 break;
1353 default:
1354 FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
1355 AL_reg(context));
1356 break;
1358 break;
1360 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
1361 TRACE("Get functionality/state information\n");
1362 if (BX_reg(context) == 0x0000)
1364 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
1365 context->SegEs,
1366 context->Edi);
1367 SET_AL( context, 0x1b ); /* Function is supported */
1368 INT10_FillStateInformation( ptr, data );
1370 break;
1372 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
1373 FIXME("Save/Restore Video State - Not Supported\n");
1374 break;
1376 case 0xef: /* get video mode for hercules-compatibles */
1377 /* There's no reason to really support this */
1378 /* is there?....................(A.C.) */
1379 TRACE("Just report the video not hercules compatible\n");
1380 SET_DX( context, 0xffff );
1381 break;
1383 case 0x4f: /* VESA */
1384 INT10_HandleVESA(context);
1385 break;
1387 case 0xfe: /* GET SHADOW BUFFER */
1388 TRACE( "GET SHADOW BUFFER %lx:%x - ignored\n",
1389 context->SegEs, DI_reg(context) );
1390 break;
1392 default:
1393 FIXME("Unknown - 0x%x\n", AH_reg(context));
1394 INT_BARF( context, 0x10 );
1399 /**********************************************************************
1400 * DOSVM_PutChar
1402 * Write single character to VGA console at the current
1403 * cursor position and updates the BIOS cursor position.
1405 void WINAPI DOSVM_PutChar( BYTE ascii )
1407 BIOSDATA *data = DOSVM_BiosData();
1408 unsigned xpos, ypos;
1410 TRACE("char: 0x%02x(%c)\n", ascii, ascii);
1412 INT10_InitializeVideoMode( data );
1414 VGA_PutChar( ascii );
1415 VGA_GetCursorPos( &xpos, &ypos );
1416 INT10_SetCursorPos( data, 0, xpos, ypos );