ole32: Return error instead of asserting if storage file is corrupt.
[wine.git] / dlls / winedos / int10.c
bloba3a4cd5cf831d08c1f8dd55fb62dcbaabc14fe4d
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 "vga.h"
27 #include "wine/debug.h"
28 #include "dosexe.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(int);
33 * Display combination code for active display.
35 * Values (hex):
36 * 00 - no display
37 * 01 - monochrome adapter w/ monochrome display
38 * 02 - CGA w/ color display
39 * 03 - reserved
40 * 04 - EGA w/ color display
41 * 05 - EGA w/ monochrome display
42 * 06 - PGA w/ color display
43 * 07 - VGA w/ monochrome analog display
44 * 08 - VGA w/ color analog display
45 * 09 - reserved
46 * 0A - MCGA w/ digital color display
47 * 0B - MCGA w/ monochrome analog display
48 * 0C - MCGA w/ color analog display
49 * FF - unknown display type
51 #define INT10_DCC 0x08
53 #include "pshpack1.h"
56 * Structure for DOS data that can be accessed directly from applications.
57 * This structure must be correctly packed.
59 typedef struct _INT10_HEAP {
60 BYTE StaticModeSupport[7]; /* modes supported 1..7 */
61 BYTE StaticScanlineSupport; /* scan lines supported */
62 BYTE StaticNumberCharBlocks; /* total number of char blocks */
63 BYTE StaticActiveCharBlocks; /* max number of active char blocks */
64 WORD StaticMiscFlags; /* misc function support flags */
65 WORD StaticReserved1; /* reserved */
66 BYTE StaticSavePointerFlags; /* save pointer function flags */
67 BYTE StaticReserved2; /* reserved */
69 WORD VesaCurrentMode;
70 WORD VesaModeList[64];
71 char VesaOEMName[32];
72 char VesaProductName[32];
73 char VesaProductRev[32];
74 char VesaVendorName[32];
76 WORD WineHeapSegment;
77 } INT10_HEAP;
80 * Structure for VBE Mode Info Block. See the VBE 3.0 standard for details.
81 * This structure must be correctly packed.
83 struct _ModeInfoBlock {
84 WORD ModeAttributes; /* 0x00 */
85 BYTE WinAAttributes; /* 0x02 */
86 BYTE WinBAttributes; /* 0x03 */
87 WORD WinGranularity; /* 0x04 */
88 WORD WinSize; /* 0x06 */
89 WORD WinASegment; /* 0x08 */
90 WORD WinBSegment; /* 0x0A */
91 DWORD WinFuncPtr; /* 0x0C */
92 WORD BytesPerScanLine; /* 0x10 */
93 /* mandatory for VBE 1.2+ */
94 WORD XResolution; /* 0x12 */
95 WORD YResolution; /* 0x14 */
96 BYTE XCharSize; /* 0x16 */
97 BYTE YCharSize; /* 0x17 */
98 BYTE NumberOfPlanes; /* 0x18 */
99 BYTE BitsPerPixel; /* 0x19 */
100 BYTE NumberOfBanks; /* 0x1A */
101 BYTE MemoryModel; /* 0x1B */
102 BYTE BankSize; /* 0x1C */
103 BYTE NumberOfImagePages; /* 0x1D */
104 BYTE Reserved1; /* 0x1E */
105 BYTE RedMaskSize; /* 0x1F */
106 BYTE RedFieldPosition; /* 0x20 */
107 BYTE GreenMaskSize; /* 0x21 */
108 BYTE GreenFieldPosition; /* 0x22 */
109 BYTE BlueMaskSize; /* 0x23 */
110 BYTE BlueFieldPosition; /* 0x24 */
111 BYTE RsvdMaskSize; /* 0x25 */
112 BYTE RsvdFieldPosition; /* 0x26 */
113 BYTE DirectColorModeInfo; /* 0x27 */
114 /* mandatory for VBE 2.0+ */
115 DWORD PhysBasePtr; /* 0x28 */
116 DWORD Reserved2; /* 0x2C */
117 WORD Reserved3; /* 0x30 */
118 /* mandatory for VBE 3.0+ */
119 WORD LinBytesPerScanLine; /* 0x32 */
120 BYTE BnkNumberOfImagePages;/* 0x34 */
121 BYTE LinNumberOfImagePages;/* 0x35 */
122 BYTE LinRedMaskSize; /* 0x36 */
123 BYTE LinRedFieldPosition; /* 0x37 */
124 BYTE LinGreenMaskSize; /* 0x38 */
125 BYTE LinGreenFieldPosition;/* 0x39 */
126 BYTE LinBlueMaskSize; /* 0x3A */
127 BYTE LinBlueFieldPosition; /* 0x3B */
128 BYTE LinRsvdMaskSize; /* 0x3C */
129 BYTE LinRsvdFieldPosition; /* 0x3D */
130 DWORD MaxPixelClock; /* 0x3E */
131 BYTE Reserved4[190]; /* 0x42 */
134 #include "poppack.h"
137 * Wine internal information about video modes.
138 * If depth is zero, the mode is considered to
139 * be a text mode.
141 typedef struct {
142 WORD Mode;
143 WORD Width;
144 WORD Height;
145 WORD Depth;
146 } INT10_MODE;
150 * List of supported video modes.
152 static const INT10_MODE INT10_modelist[] =
154 {0x0000, 40, 25, 0},
155 {0x0001, 40, 25, 0},
156 {0x0002, 80, 25, 0},
157 {0x0003, 80, 25, 0},
158 {0x0007, 80, 25, 0},
159 {0x000d, 320, 200, 4},
160 {0x000e, 640, 200, 4},
161 {0x0010, 640, 350, 4},
162 {0x0012, 640, 480, 4},
163 {0x0013, 320, 200, 8},
164 {0x006a, 800, 600, 4}, /* VESA mode, same as 0x102 */
165 {0x0100, 640, 400, 8},
166 {0x0101, 640, 480, 8},
167 {0x0102, 800, 600, 4},
168 {0x0103, 800, 600, 8},
169 {0x0104, 1024, 768, 4},
170 {0x0105, 1024, 768, 8},
171 {0x0106, 1280, 1024, 4},
172 {0x0107, 1280, 1024, 8},
173 {0x0108, 80, 60, 0},
174 {0x0109, 132, 25, 0},
175 {0x010a, 132, 43, 0},
176 {0x010b, 132, 50, 0},
177 {0x010c, 132, 60, 0},
178 {0x010d, 320, 200, 15},
179 {0x010e, 320, 200, 16},
180 {0x010f, 320, 200, 24},
181 {0x0110, 640, 480, 15},
182 {0x0111, 640, 480, 16},
183 {0x0112, 640, 480, 24},
184 {0x0113, 800, 600, 15},
185 {0x0114, 800, 600, 16},
186 {0x0115, 800, 600, 24},
187 {0x0116, 1024, 768, 15},
188 {0x0117, 1024, 768, 16},
189 {0x0118, 1024, 768, 24},
190 {0x0119, 1280, 1024, 15},
191 {0x011a, 1280, 1024, 16},
192 {0x011b, 1280, 1024, 24},
193 {0xffff, 0, 0, 0}
196 /* True if video mode is a vesa mode, false otherwise.
197 * More correct would be to use something like (x > 0xff || x == 0x6a)
198 * but as long as we have only the standard VGA and VESA modes this is ok too */
199 #define IS_VESA_MODE(x) ((x) >= 0x6a)
201 /* Forward declarations. */
202 static INT10_HEAP *INT10_GetHeap(void);
203 static void INT10_SetCursorPos(BIOSDATA*, unsigned, unsigned, unsigned);
206 /**********************************************************************
207 * INT10_FindMode
209 static const INT10_MODE *INT10_FindMode( WORD mode )
211 const INT10_MODE *ptr = INT10_modelist;
214 * Filter out flags.
216 mode &= 0x17f;
218 while (ptr->Mode != 0xffff)
220 if (ptr->Mode == mode)
221 return ptr;
222 ptr++;
225 return NULL;
229 /**********************************************************************
230 * INT10_FillControllerInformation
232 * Fill 256-byte (VBE1.x) or 512-byte buffer (VBE2.0+) with
233 * capabilities of the video controller.
235 static void INT10_FillControllerInformation( BYTE *buffer )
237 INT10_HEAP *heap = INT10_GetHeap();
239 /* 00 - BYTE[4]: signature */
240 memmove( buffer, "VESA", 4 );
242 /* 04 - WORD: version number */
243 *(WORD*)(buffer + 4) = 0x0300; /* version 3.0 */
245 /* 06 - DWORD: pointer to OEM name */
246 *(SEGPTR*)(buffer + 6) = MAKESEGPTR( heap->WineHeapSegment,
247 offsetof(INT10_HEAP,
248 VesaOEMName) );
251 * 10 - DWORD: capabilities flags
252 * Bits:
253 * 0 - DAC can be switched into 8-bit mode
254 * 1 - non-VGA controller
255 * 2 - programmed DAC with blank bit
256 * 3 - controller supports hardware stereoscopic signalling
257 * 4 - =0 stereo signalling via external VESA stereo connector
258 * =1 stereo signalling via VESA EVC connector
259 * 5 - controller supports hardware mouse cursor
260 * 6 - controller supports hardware clipping
261 * 7 - controller supports transparent BitBLT
262 * 8-31 - reserved (0)
264 *(DWORD*)(buffer + 10) = 0; /* FIXME */
266 /* 14 - DWORD: pointer to list of supported VESA and OEM video modes */
267 *(SEGPTR*)(buffer + 14) = MAKESEGPTR( heap->WineHeapSegment,
268 offsetof(INT10_HEAP,
269 VesaModeList) );
271 /* 18 - WORD: total amount of video memory in 64K blocks */
272 *(WORD*)(buffer + 18) = 16; /* FIXME */
274 /* 20 - WORD: OEM software version (BCD, high byte = major) */
275 *(WORD*)(buffer + 20) = 0x0100; /* version 1.0 */
277 /* 22 - DWORD: pointer to vendor name */
278 *(SEGPTR*)(buffer + 22) = MAKESEGPTR( heap->WineHeapSegment,
279 offsetof(INT10_HEAP,
280 VesaVendorName) );
282 /* 26 - DWORD: pointer to product name */
283 *(SEGPTR*)(buffer + 26) = MAKESEGPTR( heap->WineHeapSegment,
284 offsetof(INT10_HEAP,
285 VesaProductName) );
287 /* 30 - DWORD: pointer to product revision string */
288 *(SEGPTR*)(buffer + 30) = MAKESEGPTR( heap->WineHeapSegment,
289 offsetof(INT10_HEAP,
290 VesaProductRev) );
292 /* 34 - WORD: VBE/AF version (if capabilities bit 3 set) */
293 *(WORD*)(buffer + 34) = 0;
296 * 36 - DWORD: pointer to list of accelerated modes
297 * (if capabilities bit 3 set)
299 *(SEGPTR*)(buffer + 36) = 0;
301 /* 40 - BYTE[216]: reserved for VBE implementation, set to zero */
302 memset( buffer + 40, 216, 0 );
305 * 256 - BYTE[256]: reserved for VBE3.0 implementation,
306 * ignored in order to support older programs
311 /**********************************************************************
312 * INT10_FillModeInformation
314 * Fill 256-byte buffer with extended information about display mode.
316 * Returns FALSE if mode is unknown and TRUE is mode is known
317 * even if it is not supported.
319 static BOOL INT10_FillModeInformation( struct _ModeInfoBlock *mib, WORD mode )
321 const INT10_MODE *ptr = INT10_FindMode( mode );
322 if (!ptr)
323 return FALSE;
326 * 00 - WORD: mode attributes
327 * Bits:
328 * 0 - Mode supported by present hardware configuration.
329 * 1 - Optional information available. Must be =1 for VBE v1.2+.
330 * 2 - BIOS output supported.
331 * Int10 functions 01, 02, 06, 07, 09, 0a and 0e are supported.
332 * 3 - Set if color, clear if monochrome.
333 * 4 - Set if graphics mode, clear if text mode.
334 * 5 - Mode is not VGA-compatible if set.
335 * VGA-compatible modes support standard VGA I/O ports.
336 * 6 - Bank-switched (or windowed) mode is not supported if set.
337 * 7 - Linear framebuffer mode supported.
338 * 8 - Double scanning supported.
339 * 9 - Interlaced operation supported.
340 * 10 - Triple buffering supported.
341 * 11 - Stereoscopic display supported.
342 * 12 - Dual display start address supported.
343 * 13-15 - Reserved.
346 WORD attr = 0x000a; /* color mode, optional info */
349 * FIXME: Attribute handling is incomplete.
352 /* Mode supported? FIXME: correct value */
353 attr |= 0x0001;
355 /* Graphical mode? */
356 if (ptr->Depth)
357 attr |= 0x0010;
359 /* Not VGA-compatible? */
360 if (IS_VESA_MODE(mode))
361 attr |= 0x0020;
363 mib->ModeAttributes = attr;
367 * 02 - BYTE[2]: window attributes, window A and window B
368 * Bits:
369 * 0 - Window exists.
370 * 1 - Window is readable.
371 * 2 - Window is writable.
372 * 3-7 - Reserved.
374 mib->WinAAttributes = 0x07; /* window A exists, readable and writable */
375 mib->WinBAttributes = 0x00; /* window B not supported */
377 /* 04 - WORD: window granularity in KB */
378 mib->WinGranularity = 64;
380 /* 06 - WORD: window size in KB */
381 mib->WinSize = 64;
383 /* 08 - WORD[2]: start segments, window A and window B */
384 mib->WinASegment = 0xa000; /* window A segment */
385 mib->WinBSegment = 0x0000; /* window B not supported */
387 /* 12 - DWORD: window positioning function */
388 mib->WinFuncPtr = 0; /* not supported */
390 /* 16 - WORD: bytes per scan line */
391 /* FIXME: is this always correct? */
392 mib->BytesPerScanLine = ptr->Width * (ptr->Depth ? (ptr->Depth + 7) / 8 : 1);
394 /* 18 - WORD: width in pixels (graphics) or characters (text) */
395 mib->XResolution = ptr->Width;
397 /* 20 - WORD: height in pixels (graphics) or characters (text) */
398 mib->YResolution = ptr->Height;
400 /* 22 - BYTE: width of character cell in pixels */
401 mib->XCharSize = 0; /* FIXME */
403 /* 23 - BYTE: height of character cell in pixels */
404 mib->YCharSize = 0; /* FIXME */
406 /* 24 - BYTE: number of memory planes */
407 mib->NumberOfPlanes = 1; /* FIXME */
409 /* 25 - BYTE: number of bits per pixel */
410 mib->BitsPerPixel = ptr->Depth; /* FIXME: text modes? reserved bits? */
412 /* 26 - BYTE: number of banks */
413 mib->NumberOfBanks = 1; /* FIXME */
416 * 27 - BYTE: memory model type
417 * Values (hex):
418 * 00 - Text mode
419 * 01 - CGA graphics
420 * 02 - Hercules graphics
421 * 03 - Planar
422 * 04 - Packed pixel
423 * 05 - Non-chain 4, 256 color
424 * 06 - Direct color
425 * 07 - YUV
426 * 08-0F - Reserved for VESA.
427 * 10-FF - OEM memory models.
429 if (!ptr->Depth)
430 mib->MemoryModel = 0; /* text mode */
431 else
432 mib->MemoryModel = 3; /* FIXME */
434 /* 28 - BYTE: size of bank in KB */
435 mib->BankSize = 0; /* FIXME */
437 /* 29 - BYTE: number of image pages (less one) in video RAM */
438 mib->NumberOfImagePages = 0; /* FIXME */
440 /* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
441 mib->Reserved1 = 0x01;
444 * 31,33,35 - BYTE: red/green/blue mask size
445 * Size of red/green/blue color component in bits.
446 * 32,34,36 - BYTE: red/green/blue field position
447 * Bit position of the least significant bit of red/green/blue color
448 * component.
449 * Both should be only used when memory model is direct color or YUV but
450 * "Imperium Romanum" uses this fields even when memory model is planar.
451 * So always fill this fields when we have a depth bigger then 8, otherwise
452 * set them to zero.
454 switch (ptr->Depth) {
455 case 24:
456 mib->RedMaskSize = 8;
457 mib->GreenMaskSize = 8;
458 mib->BlueMaskSize = 8;
459 mib->RsvdMaskSize = 0;
460 mib->RedFieldPosition = 16;
461 mib->GreenFieldPosition = 8;
462 mib->BlueFieldPosition = 0;
463 mib->RsvdFieldPosition = 0;
464 break;
465 case 16:
466 mib->RedMaskSize = 5;
467 mib->GreenMaskSize = 6;
468 mib->BlueMaskSize = 5;
469 mib->RsvdMaskSize = 0;
470 mib->RedFieldPosition = 11;
471 mib->GreenFieldPosition = 5;
472 mib->BlueFieldPosition = 0;
473 mib->RsvdFieldPosition = 0;
474 break;
475 case 15:
476 mib->RedMaskSize = 5;
477 mib->GreenMaskSize = 5;
478 mib->BlueMaskSize = 5;
479 mib->RsvdMaskSize = 1;
480 mib->RedFieldPosition = 10;
481 mib->GreenFieldPosition = 5;
482 mib->BlueFieldPosition = 0;
483 mib->RsvdFieldPosition = 15;
484 break;
485 default:
486 mib->RedMaskSize = 0;
487 mib->GreenMaskSize = 0;
488 mib->BlueMaskSize = 0;
489 mib->RsvdMaskSize = 0;
490 mib->RedFieldPosition = 0;
491 mib->GreenFieldPosition = 0;
492 mib->BlueFieldPosition = 0;
493 mib->RsvdFieldPosition = 0;
494 break;
498 * 39 - BYTE: direct color mode info
499 * Bits:
500 * 0 - Set if color ramp is programmable.
501 * 1 - Set if bytes in reserved field may be used by application.
503 mib->DirectColorModeInfo = 0; /* not supported */
505 /* 40 - DWORD: physical address of linear video buffer */
506 mib->PhysBasePtr = 0; /* not supported */
508 /* 44 - DWORD: reserved, always zero */
509 mib->Reserved2 = 0;
511 /* 48 - WORD: reserved, always zero */
512 mib->Reserved3 = 0;
514 /* 50 - WORD: bytes per scan line in linear modes */
515 mib->LinBytesPerScanLine = mib->BytesPerScanLine;
517 /* 52 - BYTE: number of images (less one) for banked video modes */
518 mib->BnkNumberOfImagePages = 0; /* FIXME */
520 /* 53 - BYTE: number of images (less one) for linear video modes */
521 mib->LinNumberOfImagePages = mib->BnkNumberOfImagePages;
523 /* 54 - BYTE: red mask size (linear modes) */
524 mib->LinRedMaskSize = mib->RedMaskSize;
526 /* 55 - BYTE: red field position (linear modes) */
527 mib->LinRedFieldPosition = mib->RedFieldPosition;
529 /* 56 - BYTE: green mask size (linear modes) */
530 mib->LinGreenMaskSize = mib->GreenMaskSize;
532 /* 57 - BYTE: green field size (linear modes) */
533 mib->LinGreenFieldPosition = mib->GreenFieldPosition;
535 /* 58 - BYTE: blue mask size (linear modes) */
536 mib->LinBlueMaskSize = mib->BlueMaskSize;
538 /* 59 - BYTE: blue field position (linear modes) */
539 mib->LinBlueFieldPosition = mib->BlueFieldPosition;
541 /* 60 - BYTE: reserved mask size (linear modes) */
542 mib->LinRsvdMaskSize = mib->RsvdMaskSize;
544 /* 61 - BYTE: reserved mask position (linear modes) */
545 mib->LinRsvdFieldPosition = mib->RsvdFieldPosition;
547 /* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
548 mib->MaxPixelClock = 0; /* FIXME */
550 /* 66 - BYTE[190]: reserved, set to zero */
551 memset( &mib->Reserved4, 190, 0 );
553 return TRUE;
557 /**********************************************************************
558 * INT10_FillStateInformation
560 * Fill 64-byte buffer with VGA state and functionality information.
562 static void INT10_FillStateInformation( BYTE *buffer, BIOSDATA *data )
564 INT10_HEAP *heap = INT10_GetHeap();
566 /* 00 - DWORD: address of static functionality table */
567 *(SEGPTR*)(buffer + 0) = MAKESEGPTR( heap->WineHeapSegment,
568 offsetof(INT10_HEAP,
569 StaticModeSupport) );
571 /* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
572 memmove( buffer + 4, &data->VideoMode, 30 );
574 /* 34 - BYTE: number of rows - 1 */
575 buffer[34] = data->RowsOnScreenMinus1;
577 /* 35 - WORD: bytes/character */
578 *(WORD*)(buffer + 35) = data->BytesPerChar;
580 /* 37 - BYTE: display combination code of active display */
581 buffer[37] = INT10_DCC;
583 /* 38 - BYTE: DCC of alternate display */
584 buffer[38] = 0; /* no secondary display */
586 /* 39 - WORD: number of colors supported in current mode (0000h = mono) */
587 *(WORD*)(buffer + 39) = 16; /* FIXME */
589 /* 41 - BYTE: number of pages supported in current mode */
590 buffer[41] = 1; /* FIXME */
593 * 42 - BYTE: number of scan lines active
594 * Values (hex):
595 * 00 = 200
596 * 01 = 350
597 * 02 = 400
598 * 03 = 480
600 buffer[42] = 3; /* FIXME */
602 /* 43 - BYTE: primary character block */
603 buffer[43] = 0; /* FIXME */
605 /* 44 - BYTE: secondary character block */
606 buffer[44] = 0; /* FIXME */
609 * 45 - BYTE: miscellaneous flags
610 * Bits:
611 * 0 - all modes on all displays on
612 * 1 - gray summing on
613 * 2 - monochrome display attached
614 * 3 - default palette loading disabled
615 * 4 - cursor emulation enabled
616 * 5 - 0 = intensity; 1 = blinking
617 * 6 - flat-panel display is active
618 * 7 - unused (0)
620 /* FIXME: Correct value? */
621 buffer[45] =
622 (data->VGASettings & 0x0f) |
623 ((data->ModeOptions & 1) << 4); /* cursor emulation */
626 * 46 - BYTE: non-VGA mode support
627 * Bits:
628 * 0 - BIOS supports information return for adapter interface
629 * 1 - adapter interface driver required
630 * 2 - 16-bit VGA graphics present
631 * 3 - =1 MFI attributes enabled
632 * =0 VGA attributes enabled
633 * 4 - 132-column mode supported
634 * 5-7 - reserved
636 buffer[46] = 0; /* FIXME: correct value? */
638 /* 47 - BYTE[2]: reserved, set to zero */
639 memset( buffer + 47, 2, 0 );
642 * 49 - BYTE: video memory available
643 * Values (hex):
644 * 00 - 64K
645 * 01 - 128K
646 * 02 - 192K
647 * 03 - 256K
649 buffer[49] = (data->ModeOptions & 0x60) >> 5; /* FIXME */
652 * 50 - BYTE: save pointer state flags
653 * Bits:
654 * 0 - 512 character set active
655 * 1 - dynamic save area present
656 * 2 - alpha font override active
657 * 3 - graphics font override active
658 * 4 - palette override active
659 * 5 - DCC override active
660 * 6-7 - unused (0)
662 buffer[50] = heap->StaticSavePointerFlags;
665 * 51 - BYTE: display information and status
666 * Bits:
667 * 0 - flat-panel display attached
668 * 1 - flat-panel display active
669 * 2 - color display
670 * 3-6 - reserved
671 * 7 - 640x480 flat-panel can be used simultaneously with CRT
673 buffer[51] = 4; /* FIXME: correct value? */
675 /* 52 - BYTE[12]: reserved, set to zero */
676 memset( buffer + 52, 12, 0 );
680 /**********************************************************************
681 * INT10_GetHeap
683 INT10_HEAP *INT10_GetHeap( void )
685 static INT10_HEAP *heap_pointer = 0;
687 if (!heap_pointer)
689 WORD segment;
690 int i;
692 heap_pointer = DOSVM_AllocDataUMB( sizeof(INT10_HEAP),
693 &segment,
694 0 );
696 for (i = 0; i < 7; i++)
697 heap_pointer->StaticModeSupport[i] = 0xff; /* FIXME */
699 heap_pointer->StaticScanlineSupport = 7; /* FIXME */
700 heap_pointer->StaticNumberCharBlocks = 0; /* FIXME */
701 heap_pointer->StaticActiveCharBlocks = 0; /* FIXME */
702 heap_pointer->StaticMiscFlags = 0x8ff; /* FIXME */
703 heap_pointer->StaticReserved1 = 0;
704 heap_pointer->StaticSavePointerFlags = 0x3f; /* FIXME */
705 heap_pointer->StaticReserved2 = 0;
707 for (i=0; TRUE; i++)
709 heap_pointer->VesaModeList[i] = INT10_modelist[i].Mode;
710 if (INT10_modelist[i].Mode == 0xffff)
711 break;
714 strcpy( heap_pointer->VesaOEMName, "WINE SVGA BOARD" );
715 strcpy( heap_pointer->VesaVendorName, "WINE" );
716 strcpy( heap_pointer->VesaProductName, "WINE SVGA" );
717 strcpy( heap_pointer->VesaProductRev, "2003" );
719 heap_pointer->VesaCurrentMode = 0; /* Initialized later. */
720 heap_pointer->WineHeapSegment = segment;
723 return heap_pointer;
727 /**********************************************************************
728 * INT10_SetVideoMode
730 * Change current video mode to any VGA or VESA mode.
731 * Returns TRUE if mode is supported.
733 * Mode bitfields:
734 * 0-6: .. Mode number (combined with bit 8).
735 * 7: =0 Clear screen.
736 * =1 Preserve display memory on mode change (VGA modes).
737 * 8: =0 VGA mode.
738 * =1 VESA mode.
739 * 9: .. Reserved, must be zero.
740 * 10: .. Reserved, must be zero.
741 * 11: =0 Use default refresh rate.
742 * =1 Use user specified refresh rate.
743 * 12: .. Reserved, must be zero.
744 * 13: .. Reserved, must be zero.
745 * 14: =0 Use windowed frame buffer model.
746 * =1 Use linear frame buffer model.
747 * 15: =0 Clear screen.
748 * =1 Preserve display memory on mode change (VESA modes).
750 static BOOL INT10_SetVideoMode( BIOSDATA *data, WORD mode )
752 const INT10_MODE *ptr = INT10_FindMode( mode );
753 INT10_HEAP *heap = INT10_GetHeap();
754 BOOL clearScreen = TRUE;
756 if (!ptr)
757 return FALSE;
760 * Linear framebuffer is not supported.
762 if (mode & 0x4000)
763 return FALSE;
766 * Check for VGA and VESA preserve video memory flag.
768 if ((mode & 0x0080) || (mode & 0x8000))
769 clearScreen = FALSE;
772 * Note that we do not mask out flags here on purpose.
774 heap->VesaCurrentMode = mode;
775 if (mode <= 0xff)
776 data->VideoMode = mode;
777 else
778 data->VideoMode = 0;
780 if (ptr->Depth == 0)
782 /* Text mode. */
783 TRACE( "Setting %s %dx%d text mode (screen %s)\n",
784 IS_VESA_MODE(mode) ? "VESA" : "VGA",
785 ptr->Width, ptr->Height,
786 clearScreen ? "cleared" : "preserved" );
789 * FIXME: We should check here if alpha mode could be set.
791 VGA_SetAlphaMode( ptr->Width, ptr->Height );
793 data->VideoColumns = ptr->Width;
794 data->RowsOnScreenMinus1 = ptr->Height - 1;
796 if (clearScreen)
798 VGA_ClearText( 0, 0, ptr->Height-1, ptr->Width-1, 0x07 );
799 INT10_SetCursorPos( data, 0, 0, 0 );
800 VGA_SetCursorPos( 0, 0 );
803 else
805 /* Graphics mode. */
806 TRACE( "Setting %s %dx%dx%d graphics mode (screen %s)\n",
807 IS_VESA_MODE(mode) ? "VESA" : "VGA",
808 ptr->Width, ptr->Height, ptr->Depth,
809 clearScreen ? "cleared" : "preserved" );
811 if (VGA_SetMode( ptr->Width, ptr->Height, ptr->Depth ))
812 return FALSE;
815 return TRUE;
819 /**********************************************************************
820 * INT10_GetCursorPos
822 static void INT10_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
824 *X = data->VideoCursorPos[page*2]; /* column */
825 *Y = data->VideoCursorPos[page*2+1]; /* row */
829 /**********************************************************************
830 * INT10_SetCursorPos
832 static void INT10_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
834 data->VideoCursorPos[page*2] = X;
835 data->VideoCursorPos[page*2+1] = Y;
839 /**********************************************************************
840 * INT10_InitializeVideoMode
842 * The first time this function is called VGA emulation is set to the
843 * default text mode.
845 static void INT10_InitializeVideoMode( BIOSDATA *data )
847 static BOOL already_initialized = FALSE;
848 unsigned width;
849 unsigned height;
851 if(already_initialized)
852 return;
853 already_initialized = TRUE;
855 VGA_InitAlphaMode(&width, &height);
858 * FIXME: Add more mappings between initial size and
859 * text modes.
861 if (width >= 80 && height >= 25)
862 INT10_SetVideoMode( data, 0x03 );
863 else
864 INT10_SetVideoMode( data, 0x01 );
868 /**********************************************************************
869 * INT10_HandleVESA
871 * Handler for VESA functions (int10 function 0x4f).
873 static void INT10_HandleVESA( CONTEXT86 *context )
875 BIOSDATA *data = DOSVM_BiosData();
877 switch(AL_reg(context)) {
879 case 0x00: /* RETURN CONTROLLER INFORMATION */
880 TRACE( "VESA RETURN CONTROLLER INFORMATION\n" );
882 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
883 context->SegEs,
884 context->Edi);
885 INT10_FillControllerInformation( ptr );
886 SET_AL( context, 0x4f );
887 SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
889 break;
891 case 0x01: /* RETURN MODE INFORMATION */
892 TRACE( "VESA RETURN MODE INFORMATION %04x\n", CX_reg(context) );
894 struct _ModeInfoBlock *ptr = CTX_SEG_OFF_TO_LIN(context,
895 context->SegEs,
896 context->Edi);
897 SET_AL( context, 0x4f );
898 if (INT10_FillModeInformation( ptr, CX_reg(context) ))
899 SET_AH( context, 0x00 ); /* status: success */
900 else
901 SET_AH( context, 0x01 ); /* status: failed */
903 break;
905 case 0x02: /* SET SuperVGA VIDEO MODE */
906 TRACE( "Set VESA video mode %04x\n", BX_reg(context) );
907 SET_AL( context, 0x4f ); /* function supported */
908 if (INT10_SetVideoMode( data, BX_reg(context) ))
909 SET_AH( context, 0x00 ); /* success */
910 else
911 SET_AH( context, 0x01 ); /* failed */
912 break;
914 case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
915 SET_AL( context, 0x4f );
916 SET_AH( context, 0x00 );
917 SET_BX( context, INT10_GetHeap()->VesaCurrentMode );
918 break;
920 case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
921 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
922 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
923 /* maybe we should do this instead ? */
924 /* AH_reg(context = 0x01; not implemented so just fail */
925 break;
927 case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
929 * This subfunction supports only Window A (BL_reg == 0) and
930 * is assumes that window granularity is 64k.
932 switch(BH_reg(context)) {
933 case 0x00: /* select video memory window */
934 SET_AL( context, 0x4f ); /* function supported */
935 if(BL_reg(context) == 0) {
936 VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
937 SET_AH( context, 0x00 ); /* status: successful */
938 } else
939 SET_AH( context, 0x01 ); /* status: failed */
940 break;
941 case 0x01: /* get video memory window */
942 SET_AL( context, 0x4f ); /* function supported */
943 if(BL_reg(context) == 0) {
944 SET_DX( context, VGA_GetWindowStart() / 64 / 1024 );
945 SET_AH( context, 0x00 ); /* status: successful */
946 } else
947 SET_AH( context, 0x01 ); /* status: failed */
948 break;
949 default:
950 INT_BARF( context, 0x10 );
952 break;
954 case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
955 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
956 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
957 /* maybe we should do this instead ? */
958 /* AH_reg(context = 0x001; not implemented so just fail */
959 break;
961 case 0x07: /* GET/SET DISPLAY START */
962 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
963 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
964 /* maybe we should do this instead ? */
965 /* AH_reg(context = 0x001; not implemented so just fail */
966 break;
968 case 0x08: /* GET/SET DAC PALETTE CONTROL */
969 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
970 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
971 /* maybe we should do this instead ? */
972 /* AH_reg(context = 0x001; not implemented so just fail */
973 break;
975 case 0x09: /* SET PALETTE ENTRIES */
976 FIXME("VESA Set palette entries - not implemented\n");
977 break;
979 case 0x0a: /* GET PROTECTED-MODE CODE */
980 FIXME("VESA Get protected-mode code - not implemented\n");
981 break;
983 case 0x10: /* Display Power Management Extensions */
984 FIXME("VESA Display Power Management Extensions - not implemented\n");
985 break;
987 case 0xef: /* get video mode for hercules-compatibles */
988 /* There's no reason to really support this */
989 /* is there?....................(A.C.) */
990 TRACE("Just report the video not hercules compatible\n");
991 SET_DX( context, 0xffff );
992 break;
994 case 0xff: /* Turn VESA ON/OFF */
995 /* I don't know what to do */
996 break;
998 default:
999 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
1000 break;
1005 /**********************************************************************
1006 * DOSVM_Int10Handler
1008 * Handler for int 10h (video).
1010 * NOTE:
1011 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
1012 * are present in this list. (SVGA and XGA are not) That is not
1013 * to say that all these functions should be supported, but if
1014 * anyone is brain-damaged enough to want to emulate one of these
1015 * beasts then this should get you started.
1017 * NOTE:
1018 * Several common graphical extensions used by Microsoft hook
1019 * off of here. I have *not* added them to this list (yet). They
1020 * include:
1022 * MSHERC.COM - More functionality for Hercules cards.
1023 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
1025 * Yes, MS also added this support into their mouse driver. Don't
1026 * ask me, I don't work for them.
1028 * Joseph Pranevich - 9/98
1030 * Jess Haas 2/99
1031 * Added support for Vesa. It is not complete but is a start.
1032 * NOTE: Im not sure if I did all this right or if any of it works.
1033 * Currently I don't have a program that uses Vesa that actually gets far
1034 * enough without crashing to do vesa stuff.
1036 * Added additional vga graphic support - 3/99
1038 void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
1040 BIOSDATA *data = DOSVM_BiosData();
1042 INT10_InitializeVideoMode( data );
1044 switch(AH_reg(context)) {
1046 case 0x00: /* SET VIDEO MODE */
1047 TRACE( "Set VGA video mode %02x\n", AL_reg(context) );
1048 if (!INT10_SetVideoMode( data, AL_reg(context) ))
1049 FIXME( "Unsupported VGA video mode requested: %#x\n",
1050 AL_reg(context) );
1051 break;
1053 case 0x01: /* SET CURSOR SHAPE */
1054 TRACE("Set Cursor Shape start %d end %d options %d\n",
1055 CH_reg(context) & 0x1f,
1056 CL_reg(context) & 0x1f,
1057 CH_reg(context) & 0xe0);
1058 data->VideoCursorType = CX_reg(context); /* direct copy */
1059 VGA_SetCursorShape(CH_reg(context), CL_reg(context));
1060 break;
1062 case 0x02: /* SET CURSOR POSITION */
1063 /* BH = Page Number */ /* Not supported */
1064 /* DH = Row */ /* 0 is left */
1065 /* DL = Column */ /* 0 is top */
1066 INT10_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
1067 if (BH_reg(context))
1069 FIXME("Set Cursor Position: Cannot set to page %d\n",
1070 BH_reg(context));
1072 else
1074 VGA_SetCursorPos(DL_reg(context), DH_reg(context));
1075 TRACE("Set Cursor Position: %d/%d\n", DL_reg(context),
1076 DH_reg(context));
1078 break;
1080 case 0x03: /* GET CURSOR POSITION AND SIZE */
1082 unsigned row, col;
1084 TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
1085 SET_CX( context, data->VideoCursorType );
1086 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1087 SET_DH( context, row );
1088 SET_DL( context, col );
1089 TRACE("Cursor Position: %d/%d\n", DL_reg(context), DH_reg(context));
1091 break;
1093 case 0x04: /* READ LIGHT PEN POSITION */
1094 FIXME("Read Light Pen Position - Not Supported\n");
1095 SET_AH( context, 0x00 ); /* Not down */
1096 break;
1098 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
1099 FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context));
1100 data->VideoCurPage = AL_reg(context);
1101 break;
1103 case 0x06: /* SCROLL UP WINDOW */
1104 /* AL = Lines to scroll */
1105 /* BH = Attribute */
1106 /* CH,CL = row, col upper-left */
1107 /* DH,DL = row, col lower-right */
1108 TRACE("Scroll Up Window %d\n", AL_reg(context));
1110 if (AL_reg(context) == 0)
1111 VGA_ClearText( CH_reg(context), CL_reg(context),
1112 DH_reg(context), DL_reg(context),
1113 BH_reg(context) );
1114 else
1115 VGA_ScrollUpText( CH_reg(context), CL_reg(context),
1116 DH_reg(context), DL_reg(context),
1117 AL_reg(context), BH_reg(context) );
1118 break;
1120 case 0x07: /* SCROLL DOWN WINDOW */
1121 /* AL = Lines to scroll */
1122 /* BH = Attribute */
1123 /* CH,CL = row, col upper-left */
1124 /* DH,DL = row, col lower-right */
1125 TRACE("Scroll Down Window %d\n", AL_reg(context));
1127 if (AL_reg(context) == 0)
1128 VGA_ClearText( CH_reg(context), CL_reg(context),
1129 DH_reg(context), DL_reg(context),
1130 BH_reg(context) );
1131 else
1132 VGA_ScrollDownText( CH_reg(context), CL_reg(context),
1133 DH_reg(context), DL_reg(context),
1134 AL_reg(context), BH_reg(context) );
1135 break;
1137 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1139 if (BH_reg(context)) /* Write to different page */
1141 FIXME("Read character and attribute at cursor position -"
1142 " Can't read from non-0 page\n");
1143 SET_AL( context, ' ' ); /* That page is blank */
1144 SET_AH( context, 7 );
1146 else
1148 BYTE ascii, attr;
1149 TRACE("Read Character and Attribute at Cursor Position\n");
1150 VGA_GetCharacterAtCursor(&ascii, &attr);
1151 SET_AL( context, ascii );
1152 SET_AH( context, attr );
1155 break;
1157 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1158 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
1159 /* AL = Character to display. */
1160 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
1161 /* BL = Attribute / Color */
1162 /* CX = Times to Write Char */
1163 /* Note here that the cursor is not advanced. */
1165 unsigned row, col;
1167 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1168 VGA_WriteChars(col, row,
1169 AL_reg(context),
1170 (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
1171 CX_reg(context));
1172 if (CX_reg(context) > 1)
1173 TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
1174 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1175 CX_reg(context), AL_reg(context));
1176 else
1177 TRACE("Write Character%s at Cursor Position: %c\n",
1178 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1179 AL_reg(context));
1181 break;
1183 case 0x0b:
1184 switch BH_reg(context) {
1185 case 0x00: /* SET BACKGROUND/BORDER COLOR */
1186 /* In text modes, this sets only the border... */
1187 /* According to the interrupt list and one of my books. */
1188 /* Funny though that Beyond Zork seems to indicate that it
1189 also sets up the default background attributes for clears
1190 and scrolls... */
1191 /* Bear in mind here that we do not want to change,
1192 apparently, the foreground or attribute of the background
1193 with this call, so we should check first to see what the
1194 foreground already is... FIXME */
1195 FIXME("Set Background/Border Color: %d/%d\n",
1196 BH_reg(context), BL_reg(context));
1197 break;
1198 case 0x01: /* SET PALETTE */
1199 FIXME("Set Palette - Not Supported\n");
1200 break;
1201 default:
1202 FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
1203 BH_reg(context));
1204 break;
1206 break;
1208 case 0x0c: /* WRITE GRAPHICS PIXEL */
1209 /* Not in graphics mode, can ignore w/o error */
1210 FIXME("Write Graphics Pixel - Not Supported\n");
1211 break;
1213 case 0x0d: /* READ GRAPHICS PIXEL */
1214 /* Not in graphics mode, can ignore w/o error */
1215 FIXME("Read Graphics Pixel - Not Supported\n");
1216 break;
1218 case 0x0e: /* TELETYPE OUTPUT */
1219 TRACE("Teletype Output\n");
1220 DOSVM_PutChar(AL_reg(context));
1221 break;
1223 case 0x0f: /* GET CURRENT VIDEO MODE */
1224 TRACE("Get current video mode: -> mode %d, columns %d\n", data->VideoMode, data->VideoColumns);
1225 /* Note: This should not be a constant value. */
1226 SET_AL( context, data->VideoMode );
1227 SET_AH( context, data->VideoColumns );
1228 SET_BH( context, 0 ); /* Display page 0 */
1229 break;
1231 case 0x10:
1232 switch AL_reg(context) {
1233 case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
1234 TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
1235 BL_reg(context),BH_reg(context));
1236 /* BH is the value BL is the register */
1237 VGA_SetColor16((int)BL_reg(context),(int)BH_reg(context));
1238 break;
1239 case 0x01: /* SET BORDER (OVERSCAN) */
1240 /* Text terminals have no overscan */
1241 /* I'm setting it anyway. - A.C. */
1242 TRACE("Set Border (Overscan) - Ignored but set.\n");
1243 VGA_SetColor16(16,(int)BH_reg(context));
1244 break;
1245 case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
1246 TRACE("Set all palette registers\n");
1247 /* ES:DX points to a 17 byte table of colors */
1248 /* No return data listed */
1249 /* I'll have to update my table and the default palette */
1250 VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1251 break;
1252 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
1253 FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
1254 break;
1255 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
1256 TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context));
1257 /* BL is register to read [ 0-15 ] BH is return value */
1258 SET_BH( context, VGA_GetColor16((int)BL_reg(context)) );
1259 break;
1260 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
1261 TRACE("Read Overscan (Border Color) Register\n");
1262 SET_BH( context, VGA_GetColor16(16) );
1263 break;
1264 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
1265 TRACE("Read All Palette Registers and Overscan Register\n");
1266 /* ES:DX points to a 17 byte table where the results */
1267 /* of this call should be stored. */
1268 VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1269 break;
1270 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
1272 PALETTEENTRY paldat;
1274 TRACE("Set Individual DAC register\n");
1275 paldat.peRed = DH_reg(context);
1276 paldat.peGreen = CH_reg(context);
1277 paldat.peBlue = CL_reg(context);
1278 paldat.peFlags = 0;
1279 VGA_SetPalette(&paldat,BX_reg(context)&0xFF,1);
1281 break;
1282 case 0x12: /* SET BLOCK OF DAC REGISTERS */
1284 int i;
1285 PALETTEENTRY paldat;
1286 BYTE *pt;
1288 TRACE("Set Block of DAC registers\n");
1289 pt = (BYTE*)CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx);
1290 for (i=0;i<CX_reg(context);i++)
1292 paldat.peRed = (*(pt+i*3+0)) << 2;
1293 paldat.peGreen = (*(pt+i*3+1)) << 2;
1294 paldat.peBlue = (*(pt+i*3+2)) << 2;
1295 paldat.peFlags = 0;
1296 VGA_SetPalette(&paldat,(BX_reg(context)+i)&0xFF,1);
1299 break;
1300 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
1301 FIXME("Select video DAC color page - Not Supported\n");
1302 break;
1303 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
1304 FIXME("Read individual DAC register - Not Supported\n");
1305 break;
1306 case 0x17: /* READ BLOCK OF DAC REGISTERS */
1307 FIXME("Read block of DAC registers - Not Supported\n");
1308 break;
1309 case 0x18: /* SET PEL MASK */
1310 FIXME("Set PEL mask - Not Supported\n");
1311 break;
1312 case 0x19: /* READ PEL MASK */
1313 FIXME("Read PEL mask - Not Supported\n");
1314 break;
1315 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
1316 FIXME("Get video DAC color page state - Not Supported\n");
1317 break;
1318 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
1319 FIXME("Perform Gray-scale summing - Not Supported\n");
1320 break;
1321 default:
1322 FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
1323 AL_reg(context));
1324 break;
1326 break;
1328 case 0x11: /* TEXT MODE CHARGEN */
1329 /* Note that second subfunction is *almost* identical. */
1330 /* See INTERRUPT.A for details. */
1331 switch AL_reg(context) {
1332 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
1333 case 0x10:
1334 FIXME("Load User Specified Patterns - Not Supported\n");
1335 break;
1336 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
1337 case 0x11:
1338 FIXME("Load ROM Monochrome Patterns - Not Supported\n");
1339 break;
1340 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
1341 case 0x12:
1342 FIXME(
1343 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
1344 break;
1345 case 0x03: /* SET BLOCK SPECIFIER */
1346 FIXME("Set Block Specifier - Not Supported\n");
1347 break;
1348 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
1349 case 0x14:
1350 FIXME("Load ROM 8x16 Character Set - Not Supported\n");
1351 break;
1352 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
1353 FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
1354 break;
1355 case 0x21: /* SET USER GRAPICS CHARACTERS */
1356 FIXME("Set User Graphics Characters - Not Supported\n");
1357 break;
1358 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
1359 FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
1360 break;
1361 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
1362 FIXME(
1363 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
1364 break;
1365 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
1366 FIXME("Load 8x16 Graphic Chars - Not Supported\n");
1367 break;
1368 case 0x30: /* GET FONT INFORMATION */
1369 FIXME("Get Font Information - Not Supported\n");
1370 break;
1371 default:
1372 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1373 AL_reg(context));
1374 break;
1376 break;
1378 case 0x12: /* ALTERNATE FUNCTION SELECT */
1379 switch BL_reg(context) {
1380 case 0x10: /* GET EGA INFO */
1381 TRACE("EGA info requested\n");
1382 SET_BH( context, 0x00 ); /* Color screen */
1383 SET_BL( context, data->ModeOptions >> 5 ); /* EGA memory size */
1384 SET_CX( context, data->FeatureBitsSwitches );
1385 break;
1386 case 0x20: /* ALTERNATE PRTSC */
1387 FIXME("Install Alternate Print Screen - Not Supported\n");
1388 break;
1389 case 0x30: /* SELECT VERTICAL RESOULTION */
1390 FIXME("Select vertical resolution - not supported\n");
1391 break;
1392 case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
1393 FIXME("Default palette loading - not supported\n");
1394 data->VGASettings =
1395 (data->VGASettings & 0xf7) |
1396 ((AL_reg(context) == 1) << 3);
1397 break;
1398 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
1399 FIXME("Video Addressing - Not Supported\n");
1400 break;
1401 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
1402 FIXME("Gray Scale Summing - Not Supported\n");
1403 break;
1404 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
1405 TRACE("Set cursor emulation to %d\n", AL_reg(context));
1406 data->ModeOptions =
1407 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
1408 break;
1409 case 0x36: /* VIDEO ADDRESS CONTROL */
1410 FIXME("Video Address Control - Not Supported\n");
1411 break;
1412 default:
1413 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1414 AL_reg(context));
1415 break;
1417 break;
1419 case 0x13: /* WRITE STRING */
1420 /* This one does not imply that string be at cursor. */
1421 FIXME("Write String - Not Supported\n");
1422 break;
1424 case 0x1a:
1425 switch AL_reg(context) {
1426 case 0x00: /* GET DISPLAY COMBINATION CODE */
1427 TRACE("Get Display Combination Code\n");
1428 SET_AL( context, 0x1a ); /* Function supported */
1429 SET_BL( context, INT10_DCC ); /* Active display */
1430 SET_BH( context, 0x00 ); /* No alternate display */
1431 break;
1432 case 0x01: /* SET DISPLAY COMBINATION CODE */
1433 FIXME("Set Display Combination Code - Not Supported\n");
1434 break;
1435 default:
1436 FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
1437 AL_reg(context));
1438 break;
1440 break;
1442 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
1443 TRACE("Get functionality/state information\n");
1444 if (BX_reg(context) == 0x0000)
1446 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
1447 context->SegEs,
1448 context->Edi);
1449 SET_AL( context, 0x1b ); /* Function is supported */
1450 INT10_FillStateInformation( ptr, data );
1452 break;
1454 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
1455 FIXME("Save/Restore Video State - Not Supported\n");
1456 break;
1458 case 0xef: /* get video mode for hercules-compatibles */
1459 /* There's no reason to really support this */
1460 /* is there?....................(A.C.) */
1461 TRACE("Just report the video not hercules compatible\n");
1462 SET_DX( context, 0xffff );
1463 break;
1465 case 0x4f: /* VESA */
1466 INT10_HandleVESA(context);
1467 break;
1469 case 0xfe: /* GET SHADOW BUFFER */
1470 TRACE( "GET SHADOW BUFFER %lx:%x - ignored\n",
1471 context->SegEs, DI_reg(context) );
1472 break;
1474 default:
1475 FIXME("Unknown - 0x%x\n", AH_reg(context));
1476 INT_BARF( context, 0x10 );
1481 /**********************************************************************
1482 * DOSVM_PutChar
1484 * Write single character to VGA console at the current
1485 * cursor position and updates the BIOS cursor position.
1487 void WINAPI DOSVM_PutChar( BYTE ascii )
1489 BIOSDATA *data = DOSVM_BiosData();
1490 unsigned xpos, ypos;
1492 TRACE("char: 0x%02x(%c)\n", ascii, ascii);
1494 INT10_InitializeVideoMode( data );
1496 VGA_PutChar( ascii );
1497 VGA_GetCursorPos( &xpos, &ypos );
1498 INT10_SetCursorPos( data, 0, xpos, ypos );