Assorted spelling fixes.
[wine/wine-kai.git] / dlls / winedos / int10.c
blob796b30cd9d718f6a7de5a64af044c4ddc67c51e5
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;
81 * Structure for VBE Mode Info Block. See the VBE 3.0 standard for details.
82 * This structure must be correctly packed.
84 struct _ModeInfoBlock {
85 WORD ModeAttributes; /* 0x00 */
86 BYTE WinAAttributes; /* 0x02 */
87 BYTE WinBAttributes; /* 0x03 */
88 WORD WinGranularity; /* 0x04 */
89 WORD WinSize; /* 0x06 */
90 WORD WinASegment; /* 0x08 */
91 WORD WinBSegment; /* 0x0A */
92 DWORD WinFuncPtr; /* 0x0C */
93 WORD BytesPerScanLine; /* 0x10 */
94 /* mandatory for VBE 1.2+ */
95 WORD XResolution; /* 0x12 */
96 WORD YResolution; /* 0x14 */
97 BYTE XCharSize; /* 0x16 */
98 BYTE YCharSize; /* 0x17 */
99 BYTE NumberOfPlanes; /* 0x18 */
100 BYTE BitsPerPixel; /* 0x19 */
101 BYTE NumberOfBanks; /* 0x1A */
102 BYTE MemoryModel; /* 0x1B */
103 BYTE BankSize; /* 0x1C */
104 BYTE NumberOfImagePages; /* 0x1D */
105 BYTE Reserved1; /* 0x1E */
106 BYTE RedMaskSize; /* 0x1F */
107 BYTE RedFieldPosition; /* 0x20 */
108 BYTE GreenMaskSize; /* 0x21 */
109 BYTE GreenFieldPosition; /* 0x22 */
110 BYTE BlueMaskSize; /* 0x23 */
111 BYTE BlueFieldPosition; /* 0x24 */
112 BYTE RsvdMaskSize; /* 0x25 */
113 BYTE RsvdFieldPosition; /* 0x26 */
114 BYTE DirectColorModeInfo; /* 0x27 */
115 /* mandatory for VBE 2.0+ */
116 DWORD PhysBasePtr; /* 0x28 */
117 DWORD Reserved2; /* 0x2C */
118 WORD Reserved3; /* 0x30 */
119 /* mandatory for VBE 3.0+ */
120 WORD LinBytesPerScanLine; /* 0x32 */
121 BYTE BnkNumberOfImagePages;/* 0x34 */
122 BYTE LinNumberOfImagePages;/* 0x35 */
123 BYTE LinRedMaskSize; /* 0x36 */
124 BYTE LinRedFieldPosition; /* 0x37 */
125 BYTE LinGreenMaskSize; /* 0x38 */
126 BYTE LinGreenFieldPosition;/* 0x39 */
127 BYTE LinBlueMaskSize; /* 0x3A */
128 BYTE LinBlueFieldPosition; /* 0x3B */
129 BYTE LinRsvdMaskSize; /* 0x3C */
130 BYTE LinRsvdFieldPosition; /* 0x3D */
131 DWORD MaxPixelClock; /* 0x3E */
132 BYTE Reserved4[190]; /* 0x42 */
135 #include "poppack.h"
138 * Wine internal information about video modes.
139 * If depth is zero, the mode is considered to
140 * be a text mode.
142 typedef struct {
143 WORD Mode;
144 WORD Width;
145 WORD Height;
146 WORD Depth;
147 } INT10_MODE;
151 * List of supported video modes.
153 static const INT10_MODE INT10_modelist[] =
155 {0x0000, 40, 25, 0},
156 {0x0001, 40, 25, 0},
157 {0x0002, 80, 25, 0},
158 {0x0003, 80, 25, 0},
159 {0x0007, 80, 25, 0},
160 {0x000d, 320, 200, 4},
161 {0x000e, 640, 200, 4},
162 {0x0010, 640, 350, 4},
163 {0x0012, 640, 480, 4},
164 {0x0013, 320, 200, 8},
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 /* Forward declarations. */
197 static INT10_HEAP *INT10_GetHeap(void);
198 static void INT10_SetCursorPos(BIOSDATA*, unsigned, unsigned, unsigned);
201 /**********************************************************************
202 * INT10_FindMode
204 static const INT10_MODE *INT10_FindMode( WORD mode )
206 const INT10_MODE *ptr = INT10_modelist;
209 * Filter out flags.
211 mode &= 0x17f;
213 while (ptr->Mode != 0xffff)
215 if (ptr->Mode == mode)
216 return ptr;
217 ptr++;
220 return NULL;
224 /**********************************************************************
225 * INT10_FillControllerInformation
227 * Fill 256-byte (VBE1.x) or 512-byte buffer (VBE2.0+) with
228 * capabilities of the video controller.
230 static void INT10_FillControllerInformation( BYTE *buffer )
232 INT10_HEAP *heap = INT10_GetHeap();
234 /* 00 - BYTE[4]: signature */
235 memmove( buffer, "VESA", 4 );
237 /* 04 - WORD: version number */
238 *(WORD*)(buffer + 4) = 0x0300; /* version 3.0 */
240 /* 06 - DWORD: pointer to OEM name */
241 *(SEGPTR*)(buffer + 6) = MAKESEGPTR( heap->WineHeapSegment,
242 offsetof(INT10_HEAP,
243 VesaOEMName) );
246 * 10 - DWORD: capabilities flags
247 * Bits:
248 * 0 - DAC can be switched into 8-bit mode
249 * 1 - non-VGA controller
250 * 2 - programmed DAC with blank bit
251 * 3 - controller supports hardware stereoscopic signalling
252 * 4 - =0 stereo signalling via external VESA stereo connector
253 * =1 stereo signalling via VESA EVC connector
254 * 5 - controller supports hardware mouse cursor
255 * 6 - controller supports hardware clipping
256 * 7 - controller supports transparent BitBLT
257 * 8-31 - reserved (0)
259 *(DWORD*)(buffer + 10) = 0; /* FIXME */
261 /* 14 - DWORD: pointer to list of supported VESA and OEM video modes */
262 *(SEGPTR*)(buffer + 14) = MAKESEGPTR( heap->WineHeapSegment,
263 offsetof(INT10_HEAP,
264 VesaModeList) );
266 /* 18 - WORD: total amount of video memory in 64K blocks */
267 *(WORD*)(buffer + 18) = 16; /* FIXME */
269 /* 20 - WORD: OEM software version (BCD, high byte = major) */
270 *(WORD*)(buffer + 20) = 0x0100; /* version 1.0 */
272 /* 22 - DWORD: pointer to vendor name */
273 *(SEGPTR*)(buffer + 22) = MAKESEGPTR( heap->WineHeapSegment,
274 offsetof(INT10_HEAP,
275 VesaVendorName) );
277 /* 26 - DWORD: pointer to product name */
278 *(SEGPTR*)(buffer + 26) = MAKESEGPTR( heap->WineHeapSegment,
279 offsetof(INT10_HEAP,
280 VesaProductName) );
282 /* 30 - DWORD: pointer to product revision string */
283 *(SEGPTR*)(buffer + 30) = MAKESEGPTR( heap->WineHeapSegment,
284 offsetof(INT10_HEAP,
285 VesaProductRev) );
287 /* 34 - WORD: VBE/AF version (if capabilities bit 3 set) */
288 *(WORD*)(buffer + 34) = 0;
291 * 36 - DWORD: pointer to list of accelerated modes
292 * (if capabilities bit 3 set)
294 *(SEGPTR*)(buffer + 36) = 0;
296 /* 40 - BYTE[216]: reserved for VBE implementation, set to zero */
297 memset( buffer + 40, 216, 0 );
300 * 256 - BYTE[256]: reserved for VBE3.0 implementation,
301 * ignored in order to support older programs
306 /**********************************************************************
307 * INT10_FillModeInformation
309 * Fill 256-byte buffer with extended information about display mode.
311 * Returns FALSE if mode is unknown and TRUE is mode is known
312 * even if it is not supported.
314 static BOOL INT10_FillModeInformation( struct _ModeInfoBlock *mib, WORD mode )
316 const INT10_MODE *ptr = INT10_FindMode( mode );
317 if (!ptr)
318 return FALSE;
321 * 00 - WORD: mode attributes
322 * Bits:
323 * 0 - Mode supported by present hardware configuration.
324 * 1 - Optional information available. Must be =1 for VBE v1.2+.
325 * 2 - BIOS output supported.
326 * Int10 functions 01, 02, 06, 07, 09, 0a and 0e are supported.
327 * 3 - Set if color, clear if monochrome.
328 * 4 - Set if graphics mode, clear if text mode.
329 * 5 - Mode is not VGA-compatible if set.
330 * VGA-compatible modes support standard VGA I/O ports.
331 * 6 - Bank-switched (or windowed) mode is not supported if set.
332 * 7 - Linear framebuffer mode supported.
333 * 8 - Double scanning supported.
334 * 9 - Interlaced operation supported.
335 * 10 - Triple buffering supported.
336 * 11 - Stereoscopic display supported.
337 * 12 - Dual display start address supported.
338 * 13-15 - Reserved.
341 WORD attr = 0x000a; /* color mode, optional info */
344 * FIXME: Attribute handling is incomplete.
347 /* Mode supported? FIXME: correct value */
348 attr |= 0x0001;
350 /* Graphical mode? */
351 if (ptr->Depth)
352 attr |= 0x0010;
354 /* Not VGA-compatible? */
355 if (mode > 0xff)
356 attr |= 0x0020;
358 mib->ModeAttributes = attr;
362 * 02 - BYTE[2]: window attributes, window A and window B
363 * Bits:
364 * 0 - Window exists.
365 * 1 - Window is readable.
366 * 2 - Window is writable.
367 * 3-7 - Reserved.
369 mib->WinAAttributes = 0x07; /* window A exists, readable and writable */
370 mib->WinBAttributes = 0x00; /* window B not supported */
372 /* 04 - WORD: window granularity in KB */
373 mib->WinGranularity = 64;
375 /* 06 - WORD: window size in KB */
376 mib->WinSize = 64;
378 /* 08 - WORD[2]: start segments, window A and window B */
379 mib->WinASegment = 0xa000; /* window A segment */
380 mib->WinBSegment = 0x0000; /* window B not supported */
382 /* 12 - DWORD: window positioning function */
383 mib->WinFuncPtr = 0; /* not supported */
385 /* 16 - WORD: bytes per scan line */
386 /* FIXME: is this always correct? */
387 mib->BytesPerScanLine = ptr->Width * (ptr->Depth ? (ptr->Depth + 7) / 8 : 1);
389 /* 18 - WORD: width in pixels (graphics) or characters (text) */
390 mib->XResolution = ptr->Width;
392 /* 20 - WORD: height in pixels (graphics) or characters (text) */
393 mib->YResolution = ptr->Height;
395 /* 22 - BYTE: width of character cell in pixels */
396 mib->XCharSize = 0; /* FIXME */
398 /* 23 - BYTE: height of character cell in pixels */
399 mib->YCharSize = 0; /* FIXME */
401 /* 24 - BYTE: number of memory planes */
402 mib->NumberOfPlanes = 1; /* FIXME */
404 /* 25 - BYTE: number of bits per pixel */
405 mib->BitsPerPixel = ptr->Depth; /* FIXME: text modes? reserved bits? */
407 /* 26 - BYTE: number of banks */
408 mib->NumberOfBanks = 1; /* FIXME */
411 * 27 - BYTE: memory model type
412 * Values (hex):
413 * 00 - Text mode
414 * 01 - CGA graphics
415 * 02 - Hercules graphics
416 * 03 - Planar
417 * 04 - Packed pixel
418 * 05 - Non-chain 4, 256 color
419 * 06 - Direct color
420 * 07 - YUV
421 * 08-0F - Reserved for VESA.
422 * 10-FF - OEM memory models.
424 if (!ptr->Depth)
425 mib->MemoryModel = 0; /* text mode */
426 else
427 mib->MemoryModel = 3; /* FIXME */
429 /* 28 - BYTE: size of bank in KB */
430 mib->BankSize = 0; /* FIXME */
432 /* 29 - BYTE: number of image pages (less one) in video RAM */
433 mib->NumberOfImagePages = 0; /* FIXME */
435 /* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
436 mib->Reserved1 = 0x01;
439 * 31,33,35 - BYTE: red/green/blue mask size
440 * Size of red/green/blue color component in bits.
441 * 32,34,36 - BYTE: red/green/blue field position
442 * Bit position of the least significant bit of red/green/blue color
443 * component.
444 * Both should be only used when memory model is direct color or YUV but
445 * "Imperium Romanum" uses this fields even when memory model is planar.
446 * So always fill this fields when we have a depth bigger then 8, otherwise
447 * set them to zero.
449 switch (ptr->Depth) {
450 case 24:
451 mib->RedMaskSize = 8;
452 mib->GreenMaskSize = 8;
453 mib->BlueMaskSize = 8;
454 mib->RsvdMaskSize = 0;
455 mib->RedFieldPosition = 16;
456 mib->GreenFieldPosition = 8;
457 mib->BlueFieldPosition = 0;
458 mib->RsvdFieldPosition = 0;
459 break;
460 case 16:
461 mib->RedMaskSize = 5;
462 mib->GreenMaskSize = 6;
463 mib->BlueMaskSize = 5;
464 mib->RsvdMaskSize = 0;
465 mib->RedFieldPosition = 11;
466 mib->GreenFieldPosition = 5;
467 mib->BlueFieldPosition = 0;
468 mib->RsvdFieldPosition = 0;
469 break;
470 case 15:
471 mib->RedMaskSize = 5;
472 mib->GreenMaskSize = 5;
473 mib->BlueMaskSize = 5;
474 mib->RsvdMaskSize = 1;
475 mib->RedFieldPosition = 10;
476 mib->GreenFieldPosition = 5;
477 mib->BlueFieldPosition = 0;
478 mib->RsvdFieldPosition = 15;
479 break;
480 default:
481 mib->RedMaskSize = 0;
482 mib->GreenMaskSize = 0;
483 mib->BlueMaskSize = 0;
484 mib->RsvdMaskSize = 0;
485 mib->RedFieldPosition = 0;
486 mib->GreenFieldPosition = 0;
487 mib->BlueFieldPosition = 0;
488 mib->RsvdFieldPosition = 0;
489 break;
493 * 39 - BYTE: direct color mode info
494 * Bits:
495 * 0 - Set if color ramp is programmable.
496 * 1 - Set if bytes in reserved field may be used by application.
498 mib->DirectColorModeInfo = 0; /* not supported */
500 /* 40 - DWORD: physical address of linear video buffer */
501 mib->PhysBasePtr = 0; /* not supported */
503 /* 44 - DWORD: reserved, always zero */
504 mib->Reserved2 = 0;
506 /* 48 - WORD: reserved, always zero */
507 mib->Reserved3 = 0;
509 /* 50 - WORD: bytes per scan line in linear modes */
510 mib->LinBytesPerScanLine = mib->BytesPerScanLine;
512 /* 52 - BYTE: number of images (less one) for banked video modes */
513 mib->BnkNumberOfImagePages = 0; /* FIXME */
515 /* 53 - BYTE: number of images (less one) for linear video modes */
516 mib->LinNumberOfImagePages = mib->BnkNumberOfImagePages;
518 /* 54 - BYTE: red mask size (linear modes) */
519 mib->LinRedMaskSize = mib->RedMaskSize;
521 /* 55 - BYTE: red field position (linear modes) */
522 mib->LinRedFieldPosition = mib->RedFieldPosition;
524 /* 56 - BYTE: green mask size (linear modes) */
525 mib->LinGreenMaskSize = mib->GreenMaskSize;
527 /* 57 - BYTE: green field size (linear modes) */
528 mib->LinGreenFieldPosition = mib->GreenFieldPosition;
530 /* 58 - BYTE: blue mask size (linear modes) */
531 mib->LinBlueMaskSize = mib->BlueMaskSize;
533 /* 59 - BYTE: blue field position (linear modes) */
534 mib->LinBlueFieldPosition = mib->BlueFieldPosition;
536 /* 60 - BYTE: reserved mask size (linear modes) */
537 mib->LinRsvdMaskSize = mib->RsvdMaskSize;
539 /* 61 - BYTE: reserved mask position (linear modes) */
540 mib->LinRsvdFieldPosition = mib->RsvdFieldPosition;
542 /* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
543 mib->MaxPixelClock = 0; /* FIXME */
545 /* 66 - BYTE[190]: reserved, set to zero */
546 memset( &mib->Reserved4, 190, 0 );
548 return TRUE;
552 /**********************************************************************
553 * INT10_FillStateInformation
555 * Fill 64-byte buffer with VGA state and functionality information.
557 static void INT10_FillStateInformation( BYTE *buffer, BIOSDATA *data )
559 INT10_HEAP *heap = INT10_GetHeap();
561 /* 00 - DWORD: address of static functionality table */
562 *(SEGPTR*)(buffer + 0) = MAKESEGPTR( heap->WineHeapSegment,
563 offsetof(INT10_HEAP,
564 StaticModeSupport) );
566 /* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
567 memmove( buffer + 4, &data->VideoMode, 30 );
569 /* 34 - BYTE: number of rows - 1 */
570 buffer[34] = data->RowsOnScreenMinus1;
572 /* 35 - WORD: bytes/character */
573 *(WORD*)(buffer + 35) = data->BytesPerChar;
575 /* 37 - BYTE: display combination code of active display */
576 buffer[37] = INT10_DCC;
578 /* 38 - BYTE: DCC of alternate display */
579 buffer[38] = 0; /* no secondary display */
581 /* 39 - WORD: number of colors supported in current mode (0000h = mono) */
582 *(WORD*)(buffer + 39) = 16; /* FIXME */
584 /* 41 - BYTE: number of pages supported in current mode */
585 buffer[41] = 1; /* FIXME */
588 * 42 - BYTE: number of scan lines active
589 * Values (hex):
590 * 00 = 200
591 * 01 = 350
592 * 02 = 400
593 * 03 = 480
595 buffer[42] = 3; /* FIXME */
597 /* 43 - BYTE: primary character block */
598 buffer[43] = 0; /* FIXME */
600 /* 44 - BYTE: secondary character block */
601 buffer[44] = 0; /* FIXME */
604 * 45 - BYTE: miscellaneous flags
605 * Bits:
606 * 0 - all modes on all displays on
607 * 1 - gray summing on
608 * 2 - monochrome display attached
609 * 3 - default palette loading disabled
610 * 4 - cursor emulation enabled
611 * 5 - 0 = intensity; 1 = blinking
612 * 6 - flat-panel display is active
613 * 7 - unused (0)
615 /* FIXME: Correct value? */
616 buffer[45] =
617 (data->VGASettings & 0x0f) |
618 ((data->ModeOptions & 1) << 4); /* cursor emulation */
621 * 46 - BYTE: non-VGA mode support
622 * Bits:
623 * 0 - BIOS supports information return for adapter interface
624 * 1 - adapter interface driver required
625 * 2 - 16-bit VGA graphics present
626 * 3 - =1 MFI attributes enabled
627 * =0 VGA attributes enabled
628 * 4 - 132-column mode supported
629 * 5-7 - reserved
631 buffer[46] = 0; /* FIXME: correct value? */
633 /* 47 - BYTE[2]: reserved, set to zero */
634 memset( buffer + 47, 2, 0 );
637 * 49 - BYTE: video memory available
638 * Values (hex):
639 * 00 - 64K
640 * 01 - 128K
641 * 02 - 192K
642 * 03 - 256K
644 buffer[49] = (data->ModeOptions & 0x60) >> 5; /* FIXME */
647 * 50 - BYTE: save pointer state flags
648 * Bits:
649 * 0 - 512 character set active
650 * 1 - dynamic save area present
651 * 2 - alpha font override active
652 * 3 - graphics font override active
653 * 4 - palette override active
654 * 5 - DCC override active
655 * 6-7 - unused (0)
657 buffer[50] = heap->StaticSavePointerFlags;
660 * 51 - BYTE: display information and status
661 * Bits:
662 * 0 - flat-panel display attached
663 * 1 - flat-panel display active
664 * 2 - color display
665 * 3-6 - reserved
666 * 7 - 640x480 flat-panel can be used simultaneously with CRT
668 buffer[51] = 4; /* FIXME: correct value? */
670 /* 52 - BYTE[12]: reserved, set to zero */
671 memset( buffer + 52, 12, 0 );
675 /**********************************************************************
676 * INT10_GetHeap
678 INT10_HEAP *INT10_GetHeap( void )
680 static INT10_HEAP *heap_pointer = 0;
682 if (!heap_pointer)
684 WORD segment;
685 int i;
687 heap_pointer = DOSVM_AllocDataUMB( sizeof(INT10_HEAP),
688 &segment,
689 0 );
691 for (i = 0; i < 7; i++)
692 heap_pointer->StaticModeSupport[i] = 0xff; /* FIXME */
694 heap_pointer->StaticScanlineSupport = 7; /* FIXME */
695 heap_pointer->StaticNumberCharBlocks = 0; /* FIXME */
696 heap_pointer->StaticActiveCharBlocks = 0; /* FIXME */
697 heap_pointer->StaticMiscFlags = 0x8ff; /* FIXME */
698 heap_pointer->StaticReserved1 = 0;
699 heap_pointer->StaticSavePointerFlags = 0x3f; /* FIXME */
700 heap_pointer->StaticReserved2 = 0;
702 for (i=0; TRUE; i++)
704 heap_pointer->VesaModeList[i] = INT10_modelist[i].Mode;
705 if (INT10_modelist[i].Mode == 0xffff)
706 break;
709 strcpy( heap_pointer->VesaOEMName, "WINE SVGA BOARD" );
710 strcpy( heap_pointer->VesaVendorName, "WINE" );
711 strcpy( heap_pointer->VesaProductName, "WINE SVGA" );
712 strcpy( heap_pointer->VesaProductRev, "2003" );
714 heap_pointer->VesaCurrentMode = 0; /* Initialized later. */
715 heap_pointer->WineHeapSegment = segment;
718 return heap_pointer;
722 /**********************************************************************
723 * INT10_SetVideoMode
725 * Change current video mode to any VGA or VESA mode.
726 * Returns TRUE if mode is supported.
728 * Mode bitfields:
729 * 0-6: .. Mode number (combined with bit 8).
730 * 7: =0 Clear screen.
731 * =1 Preserve display memory on mode change (VGA modes).
732 * 8: =0 VGA mode.
733 * =1 VESA mode.
734 * 9: .. Reserved, must be zero.
735 * 10: .. Reserved, must be zero.
736 * 11: =0 Use default refresh rate.
737 * =1 Use user specified refresh rate.
738 * 12: .. Reserved, must be zero.
739 * 13: .. Reserved, must be zero.
740 * 14: =0 Use windowed frame buffer model.
741 * =1 Use linear frame buffer model.
742 * 15: =0 Clear screen.
743 * =1 Preserve display memory on mode change (VESA modes).
745 static BOOL INT10_SetVideoMode( BIOSDATA *data, WORD mode )
747 const INT10_MODE *ptr = INT10_FindMode( mode );
748 INT10_HEAP *heap = INT10_GetHeap();
749 BOOL clearScreen = TRUE;
751 if (!ptr)
752 return FALSE;
755 * Linear framebuffer is not supported.
757 if (mode & 0x4000)
758 return FALSE;
761 * Check for VGA and VESA preserve video memory flag.
763 if ((mode & 0x0080) || (mode & 0x8000))
764 clearScreen = FALSE;
767 * Note that we do not mask out flags here on purpose.
769 heap->VesaCurrentMode = mode;
770 if (mode <= 0xff)
771 data->VideoMode = mode;
772 else
773 data->VideoMode = 0;
775 if (ptr->Depth == 0)
777 /* Text mode. */
778 TRACE( "Setting %s %dx%d text mode (screen %s)\n",
779 mode <= 0xff ? "VGA" : "VESA",
780 ptr->Width, ptr->Height,
781 clearScreen ? "cleared" : "preserved" );
784 * FIXME: We should check here if alpha mode could be set.
786 VGA_SetAlphaMode( ptr->Width, ptr->Height );
788 data->VideoColumns = ptr->Width;
789 data->RowsOnScreenMinus1 = ptr->Height - 1;
791 if (clearScreen)
793 VGA_ClearText( 0, 0, ptr->Height-1, ptr->Width-1, 0x07 );
794 INT10_SetCursorPos( data, 0, 0, 0 );
795 VGA_SetCursorPos( 0, 0 );
798 else
800 /* Graphics mode. */
801 TRACE( "Setting %s %dx%dx%d graphics mode (screen %s)\n",
802 mode <= 0xff ? "VGA" : "VESA",
803 ptr->Width, ptr->Height, ptr->Depth,
804 clearScreen ? "cleared" : "preserved" );
806 if (VGA_SetMode( ptr->Width, ptr->Height, ptr->Depth ))
807 return FALSE;
810 return TRUE;
814 /**********************************************************************
815 * INT10_GetCursorPos
817 static void INT10_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
819 *X = data->VideoCursorPos[page*2]; /* column */
820 *Y = data->VideoCursorPos[page*2+1]; /* row */
824 /**********************************************************************
825 * INT10_SetCursorPos
827 static void INT10_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
829 data->VideoCursorPos[page*2] = X;
830 data->VideoCursorPos[page*2+1] = Y;
834 /**********************************************************************
835 * INT10_InitializeVideoMode
837 * The first time this function is called VGA emulation is set to the
838 * default text mode.
840 static void INT10_InitializeVideoMode( BIOSDATA *data )
842 static BOOL already_initialized = FALSE;
843 unsigned width;
844 unsigned height;
846 if(already_initialized)
847 return;
848 already_initialized = TRUE;
850 VGA_InitAlphaMode(&width, &height);
853 * FIXME: Add more mappings between initial size and
854 * text modes.
856 if (width >= 80 && height >= 25)
857 INT10_SetVideoMode( data, 0x03 );
858 else
859 INT10_SetVideoMode( data, 0x01 );
863 /**********************************************************************
864 * INT10_HandleVESA
866 * Handler for VESA functions (int10 function 0x4f).
868 static void INT10_HandleVESA( CONTEXT86 *context )
870 BIOSDATA *data = DOSVM_BiosData();
872 switch(AL_reg(context)) {
874 case 0x00: /* RETURN CONTROLLER INFORMATION */
875 TRACE( "VESA RETURN CONTROLLER INFORMATION\n" );
877 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
878 context->SegEs,
879 context->Edi);
880 INT10_FillControllerInformation( ptr );
881 SET_AL( context, 0x4f );
882 SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
884 break;
886 case 0x01: /* RETURN MODE INFORMATION */
887 TRACE( "VESA RETURN MODE INFORMATION %04x\n", CX_reg(context) );
889 struct _ModeInfoBlock *ptr = CTX_SEG_OFF_TO_LIN(context,
890 context->SegEs,
891 context->Edi);
892 SET_AL( context, 0x4f );
893 if (INT10_FillModeInformation( ptr, CX_reg(context) ))
894 SET_AH( context, 0x00 ); /* status: success */
895 else
896 SET_AH( context, 0x01 ); /* status: failed */
898 break;
900 case 0x02: /* SET SuperVGA VIDEO MODE */
901 TRACE( "Set VESA video mode %04x\n", BX_reg(context) );
902 SET_AL( context, 0x4f ); /* function supported */
903 if (INT10_SetVideoMode( data, BX_reg(context) ))
904 SET_AH( context, 0x00 ); /* success */
905 else
906 SET_AH( context, 0x01 ); /* failed */
907 break;
909 case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
910 SET_AL( context, 0x4f );
911 SET_AH( context, 0x00 );
912 SET_BX( context, INT10_GetHeap()->VesaCurrentMode );
913 break;
915 case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
916 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
917 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
918 /* maybe we should do this instead ? */
919 /* AH_reg(context = 0x01; not implemented so just fail */
920 break;
922 case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
924 * This subfunction supports only Window A (BL_reg == 0) and
925 * is assumes that window granularity is 64k.
927 switch(BH_reg(context)) {
928 case 0x00: /* select video memory window */
929 SET_AL( context, 0x4f ); /* function supported */
930 if(BL_reg(context) == 0) {
931 VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
932 SET_AH( context, 0x00 ); /* status: successful */
933 } else
934 SET_AH( context, 0x01 ); /* status: failed */
935 break;
936 case 0x01: /* get video memory window */
937 SET_AL( context, 0x4f ); /* function supported */
938 if(BL_reg(context) == 0) {
939 SET_DX( context, VGA_GetWindowStart() / 64 / 1024 );
940 SET_AH( context, 0x00 ); /* status: successful */
941 } else
942 SET_AH( context, 0x01 ); /* status: failed */
943 break;
944 default:
945 INT_BARF( context, 0x10 );
947 break;
949 case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
950 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
951 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
952 /* maybe we should do this instead ? */
953 /* AH_reg(context = 0x001; not implemented so just fail */
954 break;
956 case 0x07: /* GET/SET DISPLAY START */
957 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
958 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
959 /* maybe we should do this instead ? */
960 /* AH_reg(context = 0x001; not implemented so just fail */
961 break;
963 case 0x08: /* GET/SET DAC PALETTE CONTROL */
964 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
965 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
966 /* maybe we should do this instead ? */
967 /* AH_reg(context = 0x001; not implemented so just fail */
968 break;
970 case 0x09: /* SET PALETTE ENTRIES */
971 FIXME("VESA Set palette entries - not implemented\n");
972 break;
974 case 0x0a: /* GET PROTECTED-MODE CODE */
975 FIXME("VESA Get protected-mode code - not implemented\n");
976 break;
978 case 0x10: /* Display Power Management Extensions */
979 FIXME("VESA Display Power Management Extensions - not implemented\n");
980 break;
982 case 0xef: /* get video mode for hercules-compatibles */
983 /* There's no reason to really support this */
984 /* is there?....................(A.C.) */
985 TRACE("Just report the video not hercules compatible\n");
986 SET_DX( context, 0xffff );
987 break;
989 case 0xff: /* Turn VESA ON/OFF */
990 /* I don't know what to do */
991 break;
993 default:
994 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
995 break;
1000 /**********************************************************************
1001 * DOSVM_Int10Handler
1003 * Handler for int 10h (video).
1005 * NOTE:
1006 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
1007 * are present in this list. (SVGA and XGA are not) That is not
1008 * to say that all these functions should be supported, but if
1009 * anyone is brain-damaged enough to want to emulate one of these
1010 * beasts then this should get you started.
1012 * NOTE:
1013 * Several common graphical extensions used by Microsoft hook
1014 * off of here. I have *not* added them to this list (yet). They
1015 * include:
1017 * MSHERC.COM - More functionality for Hercules cards.
1018 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
1020 * Yes, MS also added this support into their mouse driver. Don't
1021 * ask me, I don't work for them.
1023 * Joseph Pranevich - 9/98
1025 * Jess Haas 2/99
1026 * Added support for Vesa. It is not complete but is a start.
1027 * NOTE: Im not sure if I did all this right or if any of it works.
1028 * Currently I don't have a program that uses Vesa that actually gets far
1029 * enough without crashing to do vesa stuff.
1031 * Added additional vga graphic support - 3/99
1033 void WINAPI DOSVM_Int10Handler( CONTEXT86 *context )
1035 BIOSDATA *data = DOSVM_BiosData();
1037 INT10_InitializeVideoMode( data );
1039 switch(AH_reg(context)) {
1041 case 0x00: /* SET VIDEO MODE */
1042 TRACE( "Set VGA video mode %02x\n", AL_reg(context) );
1043 if (!INT10_SetVideoMode( data, AL_reg(context) ))
1044 FIXME( "Unsupported VGA video mode requested: %d\n",
1045 AL_reg(context) );
1046 break;
1048 case 0x01: /* SET CURSOR SHAPE */
1049 TRACE("Set Cursor Shape start %d end %d options %d\n",
1050 CH_reg(context) & 0x1f,
1051 CL_reg(context) & 0x1f,
1052 CH_reg(context) & 0xe0);
1053 data->VideoCursorType = CX_reg(context); /* direct copy */
1054 VGA_SetCursorShape(CH_reg(context), CL_reg(context));
1055 break;
1057 case 0x02: /* SET CURSOR POSITION */
1058 /* BH = Page Number */ /* Not supported */
1059 /* DH = Row */ /* 0 is left */
1060 /* DL = Column */ /* 0 is top */
1061 INT10_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
1062 if (BH_reg(context))
1064 FIXME("Set Cursor Position: Cannot set to page %d\n",
1065 BH_reg(context));
1067 else
1069 VGA_SetCursorPos(DL_reg(context), DH_reg(context));
1070 TRACE("Set Cursor Position: %d/%d\n", DL_reg(context),
1071 DH_reg(context));
1073 break;
1075 case 0x03: /* GET CURSOR POSITION AND SIZE */
1077 unsigned row, col;
1079 TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
1080 SET_CX( context, data->VideoCursorType );
1081 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1082 SET_DH( context, row );
1083 SET_DL( context, col );
1084 TRACE("Cursor Position: %d/%d\n", DL_reg(context), DH_reg(context));
1086 break;
1088 case 0x04: /* READ LIGHT PEN POSITION */
1089 FIXME("Read Light Pen Position - Not Supported\n");
1090 SET_AH( context, 0x00 ); /* Not down */
1091 break;
1093 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
1094 FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context));
1095 data->VideoCurPage = AL_reg(context);
1096 break;
1098 case 0x06: /* SCROLL UP WINDOW */
1099 /* AL = Lines to scroll */
1100 /* BH = Attribute */
1101 /* CH,CL = row, col upper-left */
1102 /* DH,DL = row, col lower-right */
1103 TRACE("Scroll Up Window %d\n", AL_reg(context));
1105 if (AL_reg(context) == 0)
1106 VGA_ClearText( CH_reg(context), CL_reg(context),
1107 DH_reg(context), DL_reg(context),
1108 BH_reg(context) );
1109 else
1110 VGA_ScrollUpText( CH_reg(context), CL_reg(context),
1111 DH_reg(context), DL_reg(context),
1112 AL_reg(context), BH_reg(context) );
1113 break;
1115 case 0x07: /* SCROLL DOWN WINDOW */
1116 /* AL = Lines to scroll */
1117 /* BH = Attribute */
1118 /* CH,CL = row, col upper-left */
1119 /* DH,DL = row, col lower-right */
1120 TRACE("Scroll Down Window %d\n", AL_reg(context));
1122 if (AL_reg(context) == 0)
1123 VGA_ClearText( CH_reg(context), CL_reg(context),
1124 DH_reg(context), DL_reg(context),
1125 BH_reg(context) );
1126 else
1127 VGA_ScrollDownText( CH_reg(context), CL_reg(context),
1128 DH_reg(context), DL_reg(context),
1129 AL_reg(context), BH_reg(context) );
1130 break;
1132 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1134 if (BH_reg(context)) /* Write to different page */
1136 FIXME("Read character and attribute at cursor position -"
1137 " Can't read from non-0 page\n");
1138 SET_AL( context, ' ' ); /* That page is blank */
1139 SET_AH( context, 7 );
1141 else
1143 BYTE ascii, attr;
1144 TRACE("Read Character and Attribute at Cursor Position\n");
1145 VGA_GetCharacterAtCursor(&ascii, &attr);
1146 SET_AL( context, ascii );
1147 SET_AH( context, attr );
1150 break;
1152 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1153 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
1154 /* AL = Character to display. */
1155 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
1156 /* BL = Attribute / Color */
1157 /* CX = Times to Write Char */
1158 /* Note here that the cursor is not advanced. */
1160 unsigned row, col;
1162 INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1163 VGA_WriteChars(col, row,
1164 AL_reg(context),
1165 (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
1166 CX_reg(context));
1167 if (CX_reg(context) > 1)
1168 TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
1169 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1170 CX_reg(context), AL_reg(context));
1171 else
1172 TRACE("Write Character%s at Cursor Position: %c\n",
1173 (AH_reg(context) == 0x09) ? " and Attribute" : "",
1174 AL_reg(context));
1176 break;
1178 case 0x0b:
1179 switch BH_reg(context) {
1180 case 0x00: /* SET BACKGROUND/BORDER COLOR */
1181 /* In text modes, this sets only the border... */
1182 /* According to the interrupt list and one of my books. */
1183 /* Funny though that Beyond Zork seems to indicate that it
1184 also sets up the default background attributes for clears
1185 and scrolls... */
1186 /* Bear in mind here that we do not want to change,
1187 apparently, the foreground or attribute of the background
1188 with this call, so we should check first to see what the
1189 foreground already is... FIXME */
1190 FIXME("Set Background/Border Color: %d/%d\n",
1191 BH_reg(context), BL_reg(context));
1192 break;
1193 case 0x01: /* SET PALETTE */
1194 FIXME("Set Palette - Not Supported\n");
1195 break;
1196 default:
1197 FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
1198 BH_reg(context));
1199 break;
1201 break;
1203 case 0x0c: /* WRITE GRAPHICS PIXEL */
1204 /* Not in graphics mode, can ignore w/o error */
1205 FIXME("Write Graphics Pixel - Not Supported\n");
1206 break;
1208 case 0x0d: /* READ GRAPHICS PIXEL */
1209 /* Not in graphics mode, can ignore w/o error */
1210 FIXME("Read Graphics Pixel - Not Supported\n");
1211 break;
1213 case 0x0e: /* TELETYPE OUTPUT */
1214 TRACE("Teletype Output\n");
1215 DOSVM_PutChar(AL_reg(context));
1216 break;
1218 case 0x0f: /* GET CURRENT VIDEO MODE */
1219 TRACE("Get current video mode: -> mode %d, columns %d\n", data->VideoMode, data->VideoColumns);
1220 /* Note: This should not be a constant value. */
1221 SET_AL( context, data->VideoMode );
1222 SET_AH( context, data->VideoColumns );
1223 SET_BH( context, 0 ); /* Display page 0 */
1224 break;
1226 case 0x10:
1227 switch AL_reg(context) {
1228 case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
1229 TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
1230 BL_reg(context),BH_reg(context));
1231 /* BH is the value BL is the register */
1232 VGA_SetColor16((int)BL_reg(context),(int)BH_reg(context));
1233 break;
1234 case 0x01: /* SET BORDER (OVERSCAN) */
1235 /* Text terminals have no overscan */
1236 /* I'm setting it anyway. - A.C. */
1237 TRACE("Set Border (Overscan) - Ignored but set.\n");
1238 VGA_SetColor16(16,(int)BH_reg(context));
1239 break;
1240 case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
1241 TRACE("Set all palette registers\n");
1242 /* ES:DX points to a 17 byte table of colors */
1243 /* No return data listed */
1244 /* I'll have to update my table and the default palette */
1245 VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1246 break;
1247 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
1248 FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
1249 break;
1250 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER - A.C.*/
1251 TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context));
1252 /* BL is register to read [ 0-15 ] BH is return value */
1253 SET_BH( context, VGA_GetColor16((int)BL_reg(context)) );
1254 break;
1255 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER - A.C. */
1256 TRACE("Read Overscan (Border Color) Register \n");
1257 SET_BH( context, VGA_GetColor16(16) );
1258 break;
1259 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
1260 TRACE("Read All Palette Registers and Overscan Register \n");
1261 /* ES:DX points to a 17 byte table where the results */
1262 /* of this call should be stored. */
1263 VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1264 break;
1265 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
1267 PALETTEENTRY paldat;
1269 TRACE("Set Individual DAC register\n");
1270 paldat.peRed = DH_reg(context);
1271 paldat.peGreen = CH_reg(context);
1272 paldat.peBlue = CL_reg(context);
1273 paldat.peFlags = 0;
1274 VGA_SetPalette(&paldat,BX_reg(context)&0xFF,1);
1276 break;
1277 case 0x12: /* SET BLOCK OF DAC REGISTERS */
1279 int i;
1280 PALETTEENTRY paldat;
1281 BYTE *pt;
1283 TRACE("Set Block of DAC registers\n");
1284 pt = (BYTE*)CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx);
1285 for (i=0;i<CX_reg(context);i++)
1287 paldat.peRed = (*(pt+i*3+0)) << 2;
1288 paldat.peGreen = (*(pt+i*3+1)) << 2;
1289 paldat.peBlue = (*(pt+i*3+2)) << 2;
1290 paldat.peFlags = 0;
1291 VGA_SetPalette(&paldat,(BX_reg(context)+i)&0xFF,1);
1294 break;
1295 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
1296 FIXME("Select video DAC color page - Not Supported\n");
1297 break;
1298 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
1299 FIXME("Read individual DAC register - Not Supported\n");
1300 break;
1301 case 0x17: /* READ BLOCK OF DAC REGISTERS */
1302 FIXME("Read block of DAC registers - Not Supported\n");
1303 break;
1304 case 0x18: /* SET PEL MASK */
1305 FIXME("Set PEL mask - Not Supported\n");
1306 break;
1307 case 0x19: /* READ PEL MASK */
1308 FIXME("Read PEL mask - Not Supported\n");
1309 break;
1310 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
1311 FIXME("Get video DAC color page state - Not Supported\n");
1312 break;
1313 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
1314 FIXME("Perform Gray-scale summing - Not Supported\n");
1315 break;
1316 default:
1317 FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
1318 AL_reg(context));
1319 break;
1321 break;
1323 case 0x11: /* TEXT MODE CHARGEN */
1324 /* Note that second subfunction is *almost* identical. */
1325 /* See INTERRUPT.A for details. */
1326 switch AL_reg(context) {
1327 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
1328 case 0x10:
1329 FIXME("Load User Specified Patterns - Not Supported\n");
1330 break;
1331 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
1332 case 0x11:
1333 FIXME("Load ROM Monochrome Patterns - Not Supported\n");
1334 break;
1335 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
1336 case 0x12:
1337 FIXME(
1338 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
1339 break;
1340 case 0x03: /* SET BLOCK SPECIFIER */
1341 FIXME("Set Block Specifier - Not Supported\n");
1342 break;
1343 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
1344 case 0x14:
1345 FIXME("Load ROM 8x16 Character Set - Not Supported\n");
1346 break;
1347 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
1348 FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
1349 break;
1350 case 0x21: /* SET USER GRAPICS CHARACTERS */
1351 FIXME("Set User Graphics Characters - Not Supported\n");
1352 break;
1353 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
1354 FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
1355 break;
1356 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
1357 FIXME(
1358 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
1359 break;
1360 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
1361 FIXME("Load 8x16 Graphic Chars - Not Supported\n");
1362 break;
1363 case 0x30: /* GET FONT INFORMATION */
1364 FIXME("Get Font Information - Not Supported\n");
1365 break;
1366 default:
1367 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1368 AL_reg(context));
1369 break;
1371 break;
1373 case 0x12: /* ALTERNATE FUNCTION SELECT */
1374 switch BL_reg(context) {
1375 case 0x10: /* GET EGA INFO */
1376 TRACE("EGA info requested\n");
1377 SET_BH( context, 0x00 ); /* Color screen */
1378 SET_BL( context, data->ModeOptions >> 5 ); /* EGA memory size */
1379 SET_CX( context, data->FeatureBitsSwitches );
1380 break;
1381 case 0x20: /* ALTERNATE PRTSC */
1382 FIXME("Install Alternate Print Screen - Not Supported\n");
1383 break;
1384 case 0x30: /* SELECT VERTICAL RESOULTION */
1385 FIXME("Select vertical resolution - not supported\n");
1386 break;
1387 case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
1388 FIXME("Default palette loading - not supported\n");
1389 data->VGASettings =
1390 (data->VGASettings & 0xf7) |
1391 ((AL_reg(context) == 1) << 3);
1392 break;
1393 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
1394 FIXME("Video Addressing - Not Supported\n");
1395 break;
1396 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
1397 FIXME("Gray Scale Summing - Not Supported\n");
1398 break;
1399 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
1400 TRACE("Set cursor emulation to %d\n", AL_reg(context));
1401 data->ModeOptions =
1402 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
1403 break;
1404 case 0x36: /* VIDEO ADDRESS CONTROL */
1405 FIXME("Video Address Control - Not Supported\n");
1406 break;
1407 default:
1408 FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1409 AL_reg(context));
1410 break;
1412 break;
1414 case 0x13: /* WRITE STRING */
1415 /* This one does not imply that string be at cursor. */
1416 FIXME("Write String - Not Supported\n");
1417 break;
1419 case 0x1a:
1420 switch AL_reg(context) {
1421 case 0x00: /* GET DISPLAY COMBINATION CODE */
1422 TRACE("Get Display Combination Code\n");
1423 SET_AL( context, 0x1a ); /* Function supported */
1424 SET_BL( context, INT10_DCC ); /* Active display */
1425 SET_BH( context, 0x00 ); /* No alternate display */
1426 break;
1427 case 0x01: /* SET DISPLAY COMBINATION CODE */
1428 FIXME("Set Display Combination Code - Not Supported\n");
1429 break;
1430 default:
1431 FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
1432 AL_reg(context));
1433 break;
1435 break;
1437 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
1438 TRACE("Get functionality/state information\n");
1439 if (BX_reg(context) == 0x0000)
1441 BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
1442 context->SegEs,
1443 context->Edi);
1444 SET_AL( context, 0x1b ); /* Function is supported */
1445 INT10_FillStateInformation( ptr, data );
1447 break;
1449 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
1450 FIXME("Save/Restore Video State - Not Supported\n");
1451 break;
1453 case 0xef: /* get video mode for hercules-compatibles */
1454 /* There's no reason to really support this */
1455 /* is there?....................(A.C.) */
1456 TRACE("Just report the video not hercules compatible\n");
1457 SET_DX( context, 0xffff );
1458 break;
1460 case 0x4f: /* VESA */
1461 INT10_HandleVESA(context);
1462 break;
1464 case 0xfe: /* GET SHADOW BUFFER */
1465 TRACE( "GET SHADOW BUFFER %lx:%x - ignored\n",
1466 context->SegEs, DI_reg(context) );
1467 break;
1469 default:
1470 FIXME("Unknown - 0x%x\n", AH_reg(context));
1471 INT_BARF( context, 0x10 );
1476 /**********************************************************************
1477 * DOSVM_PutChar
1479 * Write single character to VGA console at the current
1480 * cursor position and updates the BIOS cursor position.
1482 void WINAPI DOSVM_PutChar( BYTE ascii )
1484 BIOSDATA *data = DOSVM_BiosData();
1485 unsigned xpos, ypos;
1487 TRACE("char: 0x%02x(%c)\n", ascii, ascii);
1489 INT10_InitializeVideoMode( data );
1491 VGA_PutChar( ascii );
1492 VGA_GetCursorPos( &xpos, &ypos );
1493 INT10_SetCursorPos( data, 0, xpos, ypos );