~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/krnl386.exe16/int10.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * BIOS interrupt 10h handler
  3  *
  4  * Copyright 1998 Ove Kåven
  5  * Copyright 1998 Joseph Pranevich
  6  *
  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.
 11  *
 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.
 16  *
 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #include "config.h"
 23 
 24 #include <stdlib.h>
 25 
 26 #include "vga.h"
 27 #include "wine/debug.h"
 28 #include "dosexe.h"
 29 
 30 WINE_DEFAULT_DEBUG_CHANNEL(int);
 31 
 32 /*
 33  * Display combination code for active display.
 34  *
 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
 50  */
 51 #define INT10_DCC 0x08
 52 
 53 #include "pshpack1.h"
 54 
 55 /*
 56  * Structure for DOS data that can be accessed directly from applications.
 57  * This structure must be correctly packed.
 58  */
 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 */
 68 
 69     WORD  VesaCurrentMode;
 70     WORD  VesaModeList[64];
 71     char  VesaOEMName[32];
 72     char  VesaProductName[32];
 73     char  VesaProductRev[32];
 74     char  VesaVendorName[32];
 75 
 76     WORD  WineHeapSegment;
 77 } INT10_HEAP;
 78 
 79 /*
 80  * Structure for VBE Mode Info Block. See the VBE 3.0 standard for details.
 81  * This structure must be correctly packed.
 82  */
 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 */
132 };
133 
134 #include "poppack.h"
135 
136 /* True if video mode is a vesa mode, false otherwise.
137  * More correct would be to use something like (x > 0xff || x == 0x6a)
138  * but as long as we have only the standard VGA and VESA modes this is ok too */
139 #define IS_VESA_MODE(x)         ((x) >= 0x6a)
140 
141 /* Forward declarations. */
142 static INT10_HEAP *INT10_GetHeap(void);
143 static void INT10_SetCursorPos(BIOSDATA*, unsigned, unsigned, unsigned);
144 
145 /**********************************************************************
146  *         INT10_FillControllerInformation
147  *
148  * Fill 256-byte (VBE1.x) or 512-byte buffer (VBE2.0+) with
149  * capabilities of the video controller.
150  */
151 static void INT10_FillControllerInformation( BYTE *buffer )
152 {
153     INT10_HEAP *heap = INT10_GetHeap();
154 
155     /* 00 - BYTE[4]: signature */
156     memmove( buffer, "VESA", 4 );
157 
158     /* 04 - WORD: version number */
159     *(WORD*)(buffer + 4) = 0x0300; /* version 3.0 */
160     
161     /* 06 - DWORD: pointer to OEM name */
162     *(SEGPTR*)(buffer + 6) = MAKESEGPTR( heap->WineHeapSegment,
163                                          offsetof(INT10_HEAP,
164                                                   VesaOEMName) );
165 
166     /*
167      * 10 - DWORD: capabilities flags 
168      * Bits:
169      *    0 - DAC can be switched into 8-bit mode
170      *    1 - non-VGA controller
171      *    2 - programmed DAC with blank bit
172      *    3 - controller supports hardware stereoscopic signalling
173      *    4 - =0 stereo signalling via external VESA stereo connector
174      *        =1 stereo signalling via VESA EVC connector
175      *    5 - controller supports hardware mouse cursor
176      *    6 - controller supports hardware clipping
177      *    7 - controller supports transparent BitBLT
178      * 8-31 - reserved (0)
179      */
180     *(DWORD*)(buffer + 10) = 0; /* FIXME */
181     
182     /* 14 - DWORD: pointer to list of supported VESA and OEM video modes */
183     *(SEGPTR*)(buffer + 14) = MAKESEGPTR( heap->WineHeapSegment,
184                                           offsetof(INT10_HEAP,
185                                                    VesaModeList) );
186 
187     /* 18 - WORD: total amount of video memory in 64K blocks */
188     *(WORD*)(buffer + 18) = 16; /* FIXME */
189 
190     /* 20 - WORD: OEM software version (BCD, high byte = major) */
191     *(WORD*)(buffer + 20) = 0x0100; /* version 1.0 */
192 
193     /* 22 - DWORD: pointer to vendor name */
194     *(SEGPTR*)(buffer + 22) = MAKESEGPTR( heap->WineHeapSegment,
195                                           offsetof(INT10_HEAP,
196                                                    VesaVendorName) );
197 
198     /* 26 - DWORD: pointer to product name */
199     *(SEGPTR*)(buffer + 26) = MAKESEGPTR( heap->WineHeapSegment,
200                                           offsetof(INT10_HEAP,
201                                                    VesaProductName) );
202 
203     /* 30 - DWORD: pointer to product revision string */
204     *(SEGPTR*)(buffer + 30) = MAKESEGPTR( heap->WineHeapSegment,
205                                           offsetof(INT10_HEAP,
206                                                    VesaProductRev) );
207 
208     /* 34 - WORD: VBE/AF version (if capabilities bit 3 set) */
209     *(WORD*)(buffer + 34) = 0;
210 
211     /*
212      * 36 - DWORD: pointer to list of accelerated modes 
213      *             (if capabilities bit 3 set) 
214      */
215     *(SEGPTR*)(buffer + 36) = 0;
216 
217     /* 40 - BYTE[216]: reserved for VBE implementation, set to zero */
218     memset( buffer + 40, 0, 216 );
219 
220     /* 
221      * 256 - BYTE[256]: reserved for VBE3.0 implementation, 
222      *                  ignored in order to support older programs
223      */
224 }
225 
226 
227 /**********************************************************************
228  *         INT10_FillModeInformation
229  *
230  * Fill 256-byte buffer with extended information about display mode.
231  *
232  * Returns FALSE if mode is unknown and TRUE is mode is known
233  * even if it is not supported.
234  */
235 static BOOL INT10_FillModeInformation( struct _ModeInfoBlock *mib, WORD mode )
236 {
237     const VGA_MODE *ptr = VGA_GetModeInfo( mode );
238     if (!ptr)
239         return FALSE;
240 
241     /*
242      * 00 - WORD: mode attributes
243      * Bits:
244      *     0 - Mode supported by present hardware configuration.
245      *     1 - Optional information available. Must be =1 for VBE v1.2+.
246      *     2 - BIOS output supported.
247      *         Int10 functions 01, 02, 06, 07, 09, 0a and 0e are supported.
248      *     3 - Set if color, clear if monochrome.
249      *     4 - Set if graphics mode, clear if text mode.
250      *     5 - Mode is not VGA-compatible if set.
251      *         VGA-compatible modes support standard VGA I/O ports.
252      *     6 - Bank-switched (or windowed) mode is not supported if set.
253      *     7 - Linear framebuffer mode supported.
254      *     8 - Double scanning supported.
255      *     9 - Interlaced operation supported.
256      *    10 - Triple buffering supported.
257      *    11 - Stereoscopic display supported.
258      *    12 - Dual display start address supported.
259      * 13-15 - Reserved.
260      */
261     {
262         WORD attr = 0x0002; /* set optional info available */
263         /* Enable color mode - if both Colors & Depth are 0, then assume monochrome*/
264         if (ptr->Colors || ptr->Depth)
265         {
266             attr |= 0x0008;
267         }
268 
269         /*
270          * FIXME: Attribute handling is incomplete.
271          */
272 
273         /* Mode supported? */
274         if (ptr->Supported)
275         {
276             attr |= 0x0001;  /* set display mode supported */
277         }
278 
279         /* Graphical mode? */
280         if (ptr->ModeType != TEXT)
281         {
282             attr |= 0x0010;  /* set graphics mode on (text mode off) */
283         }
284 
285         /* Not VGA-compatible? */
286         if (IS_VESA_MODE(mode))
287             attr |= 0x0020;    /* disable VGA ports */
288 
289         mib->ModeAttributes = attr;
290     }
291 
292     /*
293      * 02 - BYTE[2]: window attributes, window A and window B
294      * Bits:
295      *   0 - Window exists.
296      *   1 - Window is readable.
297      *   2 - Window is writable.
298      * 3-7 - Reserved.
299      */
300     mib->WinAAttributes = 0x07; /* window A exists, readable and writable */
301     mib->WinBAttributes = 0x00; /* window B not supported */
302 
303     /* 04 - WORD: window granularity in KB */
304     mib->WinGranularity = 64;
305 
306     /* 06 - WORD: window size in KB */
307     mib->WinSize = 64;
308 
309     /* 08 - WORD[2]: start segments, window A and window B */
310     mib->WinASegment = 0xa000; /* window A segment */
311     mib->WinBSegment = 0x0000; /* window B not supported */
312 
313     /* 12 - DWORD: window positioning function */
314     mib->WinFuncPtr = 0; /* not supported */
315     
316     /* 16 - WORD: bytes per scan line */
317     /* FIXME: is this always correct? */
318     mib->BytesPerScanLine = ptr->Width * (ptr->Depth ? (ptr->Depth + 7) / 8 : 1);
319 
320     /* 18 - WORD: width in pixels (graphics) or characters (text) */
321     if (ptr->ModeType == TEXT)
322     {
323         mib->XResolution = ptr->TextCols;
324     }
325     else
326     {
327         mib->XResolution = ptr->Width;
328     }
329 
330     /* 20 - WORD: height in pixels (graphics) or characters (text) */
331     if (ptr->ModeType == TEXT)
332     {
333         mib->YResolution = ptr->TextRows;
334     }
335     else
336     {
337         mib->YResolution = ptr->Height;
338     }
339 
340     /* 22 - BYTE: width of character cell in pixels */
341     mib->XCharSize = ptr->CharWidth;
342 
343     /* 23 - BYTE: height of character cell in pixels */
344     mib->YCharSize = ptr->CharHeight;
345 
346     /* 24 - BYTE: number of memory planes */
347     mib->NumberOfPlanes = 1; /* FIXME */
348 
349     /* 25 - BYTE: number of bits per pixel */
350     mib->BitsPerPixel = ptr->Depth; /* FIXME: text modes? reserved bits? */
351 
352     /* 26 - BYTE: number of banks */
353     mib->NumberOfBanks = 1; /* FIXME */
354 
355     /*
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.
368      */
369     if (ptr->ModeType == TEXT)
370         mib->MemoryModel = 0; /* text mode */
371     else
372         mib->MemoryModel = 3; /* FIXME */
373 
374     /* 28 - BYTE: size of bank in KB */
375     mib->BankSize = 0; /* FIXME */
376 
377     /* 29 - BYTE: number of image pages (less one) in video RAM */
378     mib->NumberOfImagePages = (ptr->ScreenPages)-1;
379 
380     /* 30 - BYTE: reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0) */
381     mib->Reserved1 = 0x01;
382 
383     /* 
384      * 31,33,35 - BYTE: red/green/blue mask size 
385      * Size of red/green/blue color component in bits.
386      * 32,34,36 - BYTE: red/green/blue field position 
387      * Bit position of the least significant bit of red/green/blue color
388      * component.
389      * Both should be only used when the memory model is direct color or YUV
390      * but "Imperium Romanum" uses this field even when the memory model is
391      * planar. So always fill this field when we have a depth bigger than 8,
392      * otherwise set them to zero.
393      */
394     switch (ptr->Depth) {
395         case 24:
396             mib->RedMaskSize = 8;
397             mib->GreenMaskSize = 8;
398             mib->BlueMaskSize = 8;
399             mib->RsvdMaskSize = 0;
400             mib->RedFieldPosition = 16;
401             mib->GreenFieldPosition = 8;
402             mib->BlueFieldPosition = 0;
403             mib->RsvdFieldPosition = 0;
404             break;
405         case 16:
406             mib->RedMaskSize = 5;
407             mib->GreenMaskSize = 6;
408             mib->BlueMaskSize = 5;
409             mib->RsvdMaskSize = 0;
410             mib->RedFieldPosition = 11;
411             mib->GreenFieldPosition = 5;
412             mib->BlueFieldPosition = 0;
413             mib->RsvdFieldPosition = 0;
414             break;
415         case 15:
416             mib->RedMaskSize = 5;
417             mib->GreenMaskSize = 5;
418             mib->BlueMaskSize = 5;
419             mib->RsvdMaskSize = 1;
420             mib->RedFieldPosition = 10;
421             mib->GreenFieldPosition = 5;
422             mib->BlueFieldPosition = 0;
423             mib->RsvdFieldPosition = 15;
424             break;
425         default:
426             mib->RedMaskSize = 0;
427             mib->GreenMaskSize = 0;
428             mib->BlueMaskSize = 0;
429             mib->RsvdMaskSize = 0;
430             mib->RedFieldPosition = 0;
431             mib->GreenFieldPosition = 0;
432             mib->BlueFieldPosition = 0;
433             mib->RsvdFieldPosition = 0;
434             break;
435     }
436 
437     /*
438      * 39 - BYTE: direct color mode info 
439      * Bits:
440      * 0 - Set if color ramp is programmable.
441      * 1 - Set if bytes in reserved field may be used by application.
442      */
443     mib->DirectColorModeInfo = 0; /* not supported */
444 
445     /* 40 - DWORD: physical address of linear video buffer */
446     mib->PhysBasePtr = 0; /* not supported */
447 
448     /* 44 - DWORD: reserved, always zero */
449     mib->Reserved2 = 0;
450 
451     /* 48 - WORD: reserved, always zero */
452     mib->Reserved3 = 0;
453 
454     /* 50 - WORD: bytes per scan line in linear modes */
455     mib->LinBytesPerScanLine = mib->BytesPerScanLine;
456 
457     /* 52 - BYTE: number of images (less one) for banked video modes */
458     mib->BnkNumberOfImagePages = 0; /* FIXME */
459 
460     /* 53 - BYTE: number of images (less one) for linear video modes */
461     mib->LinNumberOfImagePages = mib->BnkNumberOfImagePages;
462 
463     /* 54 - BYTE: red mask size (linear modes) */
464     mib->LinRedMaskSize = mib->RedMaskSize;
465 
466     /* 55 - BYTE: red field position (linear modes) */
467     mib->LinRedFieldPosition = mib->RedFieldPosition;
468 
469     /* 56 - BYTE: green mask size (linear modes) */
470     mib->LinGreenMaskSize = mib->GreenMaskSize;
471 
472     /* 57 - BYTE: green field size (linear modes) */
473     mib->LinGreenFieldPosition = mib->GreenFieldPosition;
474 
475     /* 58 - BYTE: blue mask size (linear modes) */
476     mib->LinBlueMaskSize = mib->BlueMaskSize;
477 
478     /* 59 - BYTE: blue field position (linear modes) */
479     mib->LinBlueFieldPosition = mib->BlueFieldPosition;
480 
481     /* 60 - BYTE: reserved mask size (linear modes) */
482     mib->LinRsvdMaskSize = mib->RsvdMaskSize;
483 
484     /* 61 - BYTE: reserved mask position (linear modes) */
485     mib->LinRsvdFieldPosition = mib->RsvdFieldPosition;
486 
487     /* 62 - DWORD: maximum pixel clock for graphics video mode, in Hz */
488     mib->MaxPixelClock = 0; /* FIXME */
489 
490     /* 66 - BYTE[190]: reserved, set to zero */
491     memset( mib->Reserved4, 0, 190 );
492 
493     return TRUE;
494 }
495 
496 
497 /**********************************************************************
498  *         INT10_FillStateInformation
499  *
500  * Fill 64-byte buffer with VGA state and functionality information.
501  */
502 static void INT10_FillStateInformation( BYTE *buffer, BIOSDATA *data )
503 {
504     INT10_HEAP *heap = INT10_GetHeap();
505 
506     /* 00 - DWORD: address of static functionality table */
507     *(SEGPTR*)(buffer + 0) = MAKESEGPTR( heap->WineHeapSegment,
508                                          offsetof(INT10_HEAP, 
509                                                   StaticModeSupport) );
510 
511     /* 04 - BYTE[30]: copy of BIOS data starting from 0x49 (VideoMode) */
512     memmove( buffer + 4, &data->VideoMode, 30 );
513 
514     /* 34 - BYTE: number of rows - 1 */
515     buffer[34] = data->RowsOnScreenMinus1;
516 
517     /* 35 - WORD: bytes/character */
518     *(WORD*)(buffer + 35) = data->BytesPerChar;
519 
520     /* 37 - BYTE: display combination code of active display */
521     buffer[37] = INT10_DCC;
522 
523     /* 38 - BYTE: DCC of alternate display */
524     buffer[38] = 0; /* no secondary display */
525 
526     /* 39 - WORD: number of colors supported in current mode (0000h = mono) */
527     *(WORD*)(buffer + 39) = 16; /* FIXME */
528 
529     /* 41 - BYTE: number of pages supported in current mode */
530     buffer[41] = 1; /* FIXME */
531 
532     /*
533      * 42 - BYTE: number of scan lines active
534      * Values (hex):
535      * 00 = 200
536      * 01 = 350
537      * 02 = 400
538      * 03 = 480
539      */
540     buffer[42] = 3; /* FIXME */
541 
542     /* 43 - BYTE: primary character block */
543     buffer[43] = 0; /* FIXME */
544 
545     /* 44 - BYTE: secondary character block */
546     buffer[44] = 0; /* FIXME */
547 
548     /*
549      * 45 - BYTE: miscellaneous flags
550      * Bits:
551      * 0 - all modes on all displays on
552      * 1 - gray summing on
553      * 2 - monochrome display attached
554      * 3 - default palette loading disabled
555      * 4 - cursor emulation enabled
556      * 5 - 0 = intensity; 1 = blinking
557      * 6 - flat-panel display is active
558      * 7 - unused (0)
559      */
560     /* FIXME: Correct value? */
561     buffer[45] =
562         (data->VGASettings & 0x0f) |
563         ((data->ModeOptions & 1) << 4); /* cursor emulation */
564 
565     /*
566      * 46 - BYTE: non-VGA mode support 
567      * Bits:
568      *   0 - BIOS supports information return for adapter interface
569      *   1 - adapter interface driver required
570      *   2 - 16-bit VGA graphics present
571      *   3 - =1 MFI attributes enabled
572      *       =0 VGA attributes enabled
573      *   4 - 132-column mode supported
574      * 5-7 - reserved
575      */
576      buffer[46] = 0; /* FIXME: correct value? */
577 
578      /* 47 - BYTE[2]: reserved, set to zero */
579      memset( buffer + 47, 0, 2 );
580 
581      /*
582       * 49 - BYTE: video memory available
583       * Values (hex):
584       * 00 - 64K
585       * 01 - 128K
586       * 02 - 192K
587       * 03 - 256K
588       */
589      buffer[49] = (data->ModeOptions & 0x60) >> 5; /* FIXME */
590 
591      /*
592       * 50 - BYTE: save pointer state flags
593       * Bits:
594       *   0 - 512 character set active
595       *   1 - dynamic save area present
596       *   2 - alpha font override active
597       *   3 - graphics font override active
598       *   4 - palette override active
599       *   5 - DCC override active
600       * 6-7 - unused (0)
601       */
602      buffer[50] = heap->StaticSavePointerFlags;
603 
604      /*
605       * 51 - BYTE: display information and status 
606       * Bits:
607       *   0 - flat-panel display attached
608       *   1 - flat-panel display active
609       *   2 - color display
610       * 3-6 - reserved
611       *   7 - 640x480 flat-panel can be used simultaneously with CRT
612       */
613      buffer[51] = 4; /* FIXME: correct value? */
614 
615      /* 52 - BYTE[12]: reserved, set to zero */
616      memset( buffer + 52, 0, 12 );
617 }
618 
619 
620 /**********************************************************************
621  *         INT10_GetHeap
622  */
623 static INT10_HEAP *INT10_GetHeap( void )
624 {
625     static INT10_HEAP *heap_pointer = 0;
626 
627     if (!heap_pointer)
628     {
629         WORD segment;
630         int  i;
631 
632         heap_pointer = DOSVM_AllocDataUMB( sizeof(INT10_HEAP), 
633                                            &segment,
634                                            0 );
635 
636         for (i = 0; i < 7; i++)
637             heap_pointer->StaticModeSupport[i] = 0xff; /* FIXME */
638 
639         heap_pointer->StaticScanlineSupport = 7;  /* FIXME */
640         heap_pointer->StaticNumberCharBlocks = 0; /* FIXME */
641         heap_pointer->StaticActiveCharBlocks = 0; /* FIXME */
642         heap_pointer->StaticMiscFlags = 0x8ff;    /* FIXME */
643         heap_pointer->StaticReserved1 = 0;
644         heap_pointer->StaticSavePointerFlags = 0x3f; /* FIXME */
645         heap_pointer->StaticReserved2 = 0;
646 
647         for (i=0; TRUE; i++)
648         {
649             heap_pointer->VesaModeList[i] = VGA_modelist[i].Mode;
650             if (VGA_modelist[i].Mode == 0xffff)
651                 break;
652         }
653 
654         strcpy( heap_pointer->VesaOEMName, "WINE SVGA BOARD" );
655         strcpy( heap_pointer->VesaVendorName, "WINE" );
656         strcpy( heap_pointer->VesaProductName, "WINE SVGA" );
657         strcpy( heap_pointer->VesaProductRev, "2008" );
658         
659         heap_pointer->VesaCurrentMode = 0; /* Initialized later. */
660         heap_pointer->WineHeapSegment = segment;
661     }
662 
663     return heap_pointer;
664 }
665 
666 
667 /**********************************************************************
668  *         INT10_SetVideoMode
669  *
670  * Change current video mode to any VGA or VESA mode.
671  * Returns TRUE if mode is supported.
672  *
673  * Mode bitfields:
674  * 0-6: .. Mode number (combined with bit 8).
675  *   7: =0 Clear screen.
676  *      =1 Preserve display memory on mode change (VGA modes).
677  *   8: =0 VGA mode.
678  *      =1 VESA mode.
679  *   9: .. Reserved, must be zero.
680  *  10: .. Reserved, must be zero.
681  *  11: =0 Use default refresh rate.
682  *      =1 Use user specified refresh rate.
683  *  12: .. Reserved, must be zero.
684  *  13: .. Reserved, must be zero.
685  *  14: =0 Use windowed frame buffer model.
686  *      =1 Use linear frame buffer model.
687  *  15: =0 Clear screen.
688  *      =1 Preserve display memory on mode change (VESA modes).
689  */
690 static BOOL INT10_SetVideoMode( BIOSDATA *data, WORD mode )
691 {
692     const VGA_MODE *ptr = VGA_GetModeInfo( mode );
693     INT10_HEAP *heap = INT10_GetHeap();
694     BOOL clearScreen = TRUE;
695 
696     if (!ptr)
697         return FALSE;
698 
699     /*
700      * Linear framebuffer is not supported.
701      * FIXME - not sure this is valid since mode 19 is 256 color & linear
702      *   of course only 1 window is addressable.
703      */
704     if (mode & 0x4000)
705         return FALSE;
706 
707     /*
708      * Check for VGA and VESA preserve video memory flag.
709      */
710     if ((mode & 0x0080) || (mode & 0x8000))
711         clearScreen = FALSE;
712 
713     /*
714      * Note that we do not mask out flags here on purpose.
715      */
716     heap->VesaCurrentMode = mode;
717     if (mode <= 0xff)
718         data->VideoMode = mode;
719     else
720         data->VideoMode = 0;
721 
722     if (ptr->ModeType == TEXT)
723     {
724         /* Text mode. */
725         TRACE( "Setting %s %dx%d text mode (screen %s)\n", 
726                IS_VESA_MODE(mode) ? "VESA" : "VGA", 
727                ptr->TextCols, ptr->TextRows,
728                clearScreen ? "cleared" : "preserved" );
729 
730         /*
731          * FIXME: We should check here if alpha mode could be set.
732          */
733         VGA_SetAlphaMode( ptr->TextCols, ptr->TextRows );
734 
735         data->VideoColumns = ptr->TextCols;
736         data->RowsOnScreenMinus1 = ptr->TextRows - 1;
737 
738         if (clearScreen)
739         {            
740             VGA_ClearText( 0, 0, ptr->TextCols-1, ptr->TextRows-1, 0x07 );
741             INT10_SetCursorPos( data, 0, 0, 0 );
742             VGA_SetCursorPos( 0, 0 );            
743         }
744     }
745     else
746     {
747         /* Graphics mode. */
748         TRACE( "Setting %s %dx%dx%d graphics mode (screen %s)\n", 
749                IS_VESA_MODE(mode) ? "VESA" : "VGA", 
750                ptr->Width, ptr->Height, ptr->Depth,
751                clearScreen ? "cleared" : "preserved" );
752 
753         if ( VGA_SetMode(mode) )
754             return FALSE;
755     }
756 
757     return TRUE;
758 }
759 
760 
761 /**********************************************************************
762  *         INT10_GetCursorPos
763  */
764 static void INT10_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
765 {
766     *X = data->VideoCursorPos[page*2];   /* column */
767     *Y = data->VideoCursorPos[page*2+1]; /* row */
768 }
769 
770 
771 /**********************************************************************
772  *         INT10_SetCursorPos
773  */
774 static void INT10_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
775 {
776     data->VideoCursorPos[page*2] = X;
777     data->VideoCursorPos[page*2+1] = Y;
778 }
779 
780 
781 /**********************************************************************
782  *         INT10_InitializeVideoMode
783  *
784  * The first time this function is called VGA emulation is set to the
785  * default text mode.
786  */
787 static void INT10_InitializeVideoMode( BIOSDATA *data )
788 {
789   static BOOL already_initialized = FALSE;
790   unsigned    width;
791   unsigned    height;
792 
793   if(already_initialized)
794     return;
795   already_initialized = TRUE;
796 
797   VGA_InitAlphaMode(&width, &height);
798 
799   /*
800    * FIXME: Add more mappings between initial size and
801    *        text modes.
802    */
803   if (width >= 80 && height >= 25)
804       INT10_SetVideoMode( data, 0x03 );
805   else
806       INT10_SetVideoMode( data, 0x01 );
807 }
808 
809 
810 /**********************************************************************
811  *          INT10_HandleVESA
812  *
813  * Handler for VESA functions (int10 function 0x4f).
814  */
815 static void INT10_HandleVESA( CONTEXT *context )
816 {
817     BIOSDATA *data = DOSVM_BiosData();
818 
819     switch(AL_reg(context)) {
820 
821     case 0x00: /* RETURN CONTROLLER INFORMATION */
822         TRACE( "VESA RETURN CONTROLLER INFORMATION\n" );
823         {
824             BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
825                                            context->SegEs, 
826                                            context->Edi);
827             INT10_FillControllerInformation( ptr );
828             SET_AL( context, 0x4f );
829             SET_AH( context, 0x00 ); /* 0x00 = successful 0x01 = failed */
830         }
831         break;
832 
833     case 0x01: /* RETURN MODE INFORMATION */
834         TRACE( "VESA RETURN MODE INFORMATION %04x\n", CX_reg(context) );
835         {
836             struct _ModeInfoBlock *ptr = CTX_SEG_OFF_TO_LIN(context,
837                                                             context->SegEs, 
838                                                             context->Edi);
839             SET_AL( context, 0x4f );
840             if (INT10_FillModeInformation( ptr, CX_reg(context) ))
841                 SET_AH( context, 0x00 ); /* status: success */
842             else
843                 SET_AH( context, 0x01 ); /* status: failed */
844         }
845         break;
846 
847     case 0x02: /* SET SuperVGA VIDEO MODE */
848         TRACE( "Set VESA video mode %04x\n", BX_reg(context) );
849         SET_AL( context, 0x4f ); /* function supported */
850         if (INT10_SetVideoMode( data, BX_reg(context) ))
851             SET_AH( context, 0x00 ); /* success */
852         else
853             SET_AH( context, 0x01 ); /* failed */
854         break;
855 
856     case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
857         SET_AL( context, 0x4f );
858         SET_AH( context, 0x00 );
859         SET_BX( context, INT10_GetHeap()->VesaCurrentMode );
860         break;
861 
862     case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
863         ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
864         /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
865         /* maybe we should do this instead ? */
866         /* AH_reg(context = 0x01;  not implemented so just fail */
867         break;
868 
869     case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
870         /*
871          * This subfunction supports only Window A (BL_reg == 0) and
872          * it assumes that window granularity is 64k.
873          */
874         switch(BH_reg(context)) {
875         case 0x00: /* select video memory window */
876             SET_AL( context, 0x4f ); /* function supported */
877             if(BL_reg(context) == 0) {
878                 VGA_SetWindowStart(DX_reg(context) * 64 * 1024);
879                 SET_AH( context, 0x00 ); /* status: successful */
880             } else
881                 SET_AH( context, 0x01 ); /* status: failed */
882             break;
883         case 0x01: /* get video memory window */
884             SET_AL( context, 0x4f ); /* function supported */
885             if(BL_reg(context) == 0) {
886                 SET_DX( context, VGA_GetWindowStart() / 64 / 1024 );
887                 SET_AH( context, 0x00 ); /* status: successful */
888             } else
889                 SET_AH( context, 0x01 ); /* status: failed */
890             break;
891         default:
892             INT_BARF( context, 0x10 );
893         }
894         break;
895 
896     case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
897         ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
898         /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
899         /* maybe we should do this instead ? */
900         /* AH_reg(context = 0x001; not implemented so just fail */
901         break;
902 
903     case 0x07: /* GET/SET DISPLAY START */
904         ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
905         /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
906         /* maybe we should do this instead ? */
907         /* AH_reg(context = 0x001; not implemented so just fail */
908         break;
909 
910     case 0x08: /* GET/SET DAC PALETTE CONTROL */
911         ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
912         /* AL_reg(context) = 0x4f; = supported so not set since not implemented */
913         /* maybe we should do this instead ? */
914         /* AH_reg(context = 0x001; not implemented so just fail */
915         break;
916 
917     case 0x09: /* SET PALETTE ENTRIES */
918         FIXME("VESA Set palette entries - not implemented\n");
919         break;
920 
921     case 0x0a: /* GET PROTECTED-MODE CODE */
922         FIXME("VESA Get protected-mode code - not implemented\n");
923         break;
924 
925     case 0x10: /* Display Power Management Extensions */
926         FIXME("VESA Display Power Management Extensions - not implemented\n");
927         break;
928 
929     case 0xef:  /* get video mode for hercules-compatibles   */
930         /* There's no reason to really support this  */
931         /* is there?....................(A.C.)       */
932         TRACE("Just report the video not hercules compatible\n");
933         SET_DX( context, 0xffff );
934         break;
935 
936     case 0xff: /* Turn VESA ON/OFF */
937         /* I don't know what to do */
938         break;
939 
940     default:
941         FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
942         break;
943     }
944 }
945 
946 
947 /**********************************************************************
948  *          DOSVM_Int10Handler
949  *
950  * Handler for int 10h (video).
951  *
952  * NOTE:
953  *    Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
954  *    are present in this list. (SVGA and XGA are not) That is not
955  *    to say that all these functions should be supported, but if
956  *    anyone is brain-damaged enough to want to emulate one of these
957  *    beasts then this should get you started.
958  *
959  * NOTE:
960  *    Several common graphical extensions used by Microsoft hook
961  *    off of here. I have *not* added them to this list (yet). They
962  *    include:
963  *
964  *    MSHERC.COM - More functionality for Hercules cards.
965  *    EGA.SYS (also MOUSE.COM) - More for EGA cards.
966  *
967  *    Yes, MS also added this support into their mouse driver. Don't
968  *    ask me, I don't work for them.
969  *
970  * Joseph Pranevich - 9/98
971  *
972  *  Jess Haas 2/99
973  *      Added support for Vesa. It is not complete but is a start.
974  *      NOTE: Im not sure if I did all this right or if any of it works.
975  *      Currently I don't have a program that uses Vesa that actually gets far
976  *      enough without crashing to do vesa stuff.
977  *
978  *      Added additional vga graphic support - 3/99
979  */
980 void WINAPI DOSVM_Int10Handler( CONTEXT *context )
981 {
982     BIOSDATA *data = DOSVM_BiosData();
983 
984     INT10_InitializeVideoMode( data );
985 
986     switch(AH_reg(context)) {
987 
988     case 0x00: /* SET VIDEO MODE */
989         TRACE( "Set VGA video mode %02x\n", AL_reg(context) );
990         if (!INT10_SetVideoMode( data, AL_reg(context) ))
991             FIXME( "Unsupported VGA video mode requested: %#x\n", 
992                    AL_reg(context) );
993         break;
994 
995     case 0x01: /* SET CURSOR SHAPE */
996         TRACE("Set Cursor Shape start %d end %d options %d\n",
997               CH_reg(context) & 0x1f,
998               CL_reg(context) & 0x1f,
999               CH_reg(context) & 0xe0);
1000         data->VideoCursorType = CX_reg(context); /* direct copy */
1001         VGA_SetCursorShape(CH_reg(context), CL_reg(context));
1002         break;
1003 
1004     case 0x02: /* SET CURSOR POSITION */
1005         /* BH = Page Number */ /* Not supported */
1006         /* DH = Row */ /* 0 is left */
1007         /* DL = Column */ /* 0 is top */
1008         INT10_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
1009         if (BH_reg(context))
1010         {
1011            FIXME("Set Cursor Position: Cannot set to page %d\n",
1012               BH_reg(context));
1013         }
1014         else
1015         {
1016            VGA_SetCursorPos(DL_reg(context), DH_reg(context));
1017            TRACE("Set Cursor Position: %d/%d\n", DL_reg(context),
1018               DH_reg(context));
1019         }
1020         break;
1021 
1022     case 0x03: /* GET CURSOR POSITION AND SIZE */
1023         {
1024           unsigned row, col;
1025 
1026           TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
1027           SET_CX( context, data->VideoCursorType );
1028           INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1029           SET_DH( context, row );
1030           SET_DL( context, col );
1031           TRACE("Cursor Position: %d/%d\n", DL_reg(context), DH_reg(context));
1032         }
1033         break;
1034 
1035     case 0x04: /* READ LIGHT PEN POSITION */
1036         FIXME("Read Light Pen Position - Not Supported\n");
1037         SET_AH( context, 0x00 ); /* Not down */
1038         break;
1039 
1040     case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
1041         FIXME("Select Active Display Page (%d) - Not Supported\n", AL_reg(context));
1042         data->VideoCurPage = AL_reg(context);
1043         break;
1044 
1045     case 0x06: /* SCROLL UP WINDOW */
1046         /* AL = Lines to scroll */
1047         /* BH = Attribute */
1048         /* CH,CL = row, col upper-left */
1049         /* DH,DL = row, col lower-right */
1050         TRACE("Scroll Up Window %d\n", AL_reg(context));
1051 
1052         if (AL_reg(context) == 0)
1053             VGA_ClearText( CH_reg(context), CL_reg(context),
1054                            DH_reg(context), DL_reg(context),
1055                            BH_reg(context) );
1056         else
1057             VGA_ScrollUpText( CH_reg(context), CL_reg(context),
1058                               DH_reg(context), DL_reg(context),
1059                               AL_reg(context), BH_reg(context) );
1060         break;
1061 
1062     case 0x07: /* SCROLL DOWN WINDOW */
1063         /* AL = Lines to scroll */
1064         /* BH = Attribute */
1065         /* CH,CL = row, col upper-left */
1066         /* DH,DL = row, col lower-right */
1067         TRACE("Scroll Down Window %d\n", AL_reg(context));
1068 
1069         if (AL_reg(context) == 0)
1070             VGA_ClearText( CH_reg(context), CL_reg(context),
1071                            DH_reg(context), DL_reg(context),
1072                            BH_reg(context) );
1073         else
1074             VGA_ScrollDownText( CH_reg(context), CL_reg(context),
1075                                 DH_reg(context), DL_reg(context),
1076                                 AL_reg(context), BH_reg(context) );
1077         break;
1078 
1079     case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1080         {
1081             if (BH_reg(context)) /* Write to different page */
1082             {
1083                 FIXME("Read character and attribute at cursor position -"
1084                       " Can't read from non-0 page\n");
1085                 SET_AL( context, ' ' ); /* That page is blank */
1086                 SET_AH( context, 7 );
1087             }
1088             else
1089            {
1090                 BYTE ascii, attr;
1091                 TRACE("Read Character and Attribute at Cursor Position\n");
1092                 VGA_GetCharacterAtCursor(&ascii, &attr);
1093                 SET_AL( context, ascii );
1094                 SET_AH( context, attr );
1095             }
1096         }
1097         break;
1098 
1099     case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
1100     case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
1101        /* AL = Character to display. */
1102        /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
1103        /* BL = Attribute / Color */
1104        /* CX = Times to Write Char */
1105        /* Note here that the cursor is not advanced. */
1106        {
1107            unsigned row, col;
1108 
1109            INT10_GetCursorPos(data,BH_reg(context),&col,&row);
1110            VGA_WriteChars(col, row,
1111                           AL_reg(context),
1112                           (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
1113                           CX_reg(context));
1114            if (CX_reg(context) > 1)
1115               TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
1116                     (AH_reg(context) == 0x09) ? " and Attribute" : "",
1117                  CX_reg(context), AL_reg(context));
1118            else
1119               TRACE("Write Character%s at Cursor Position: %c\n",
1120                     (AH_reg(context) == 0x09) ? " and Attribute" : "",
1121                 AL_reg(context));
1122        }
1123        break;
1124 
1125     case 0x0b:
1126         switch BH_reg(context) {
1127         case 0x00: /* SET BACKGROUND/BORDER COLOR */
1128             /* In text modes, this sets only the border... */
1129             /* According to the interrupt list and one of my books. */
1130             /* Funny though that Beyond Zork seems to indicate that it
1131                also sets up the default background attributes for clears
1132                and scrolls... */
1133             /* Bear in mind here that we do not want to change,
1134                apparently, the foreground or attribute of the background
1135                with this call, so we should check first to see what the
1136                foreground already is... FIXME */
1137 
1138             /* For CGA modes, background color change is the same as writing
1139                to I/O address 0x3d9 bit 4  */
1140             if(data->VideoMode >= 4 && data->VideoMode <= 6)
1141             {
1142               VGA_SetBright((BL_reg(context) & 0x10) != 0);
1143               VGA_UpdatePalette();
1144             }
1145             else FIXME("Set Background/Border Color: %d/%d\n",
1146               BH_reg(context), BL_reg(context));
1147             break;
1148         case 0x01: /* SET PALETTE */
1149 
1150             /* For CGA modes, palette color change is the same as writing
1151                to I/O address 0x3d9 bit 5 */
1152             if(data->VideoMode >= 4 && data->VideoMode <= 6)
1153             {
1154               VGA_SetPaletteIndex(BL_reg(context) & 1);
1155               VGA_UpdatePalette();
1156             }
1157             else FIXME("Set Palette - Not Supported: %02X\n", BL_reg(context));
1158             break;
1159         default:
1160             FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
1161                BH_reg(context));
1162             break;
1163         }
1164         break;
1165 
1166     case 0x0c: /* WRITE GRAPHICS PIXEL */
1167 
1168         /* Only supported in CGA mode for now */
1169         if(data->VideoMode >= 4 && data->VideoMode <= 6)
1170         {
1171           VGA_WritePixel(AL_reg(context), BH_reg(context), CX_reg(context), DX_reg(context));
1172         }
1173         else FIXME("Write pixel not implemented for current mode\n");
1174         break;
1175 
1176     case 0x0d: /* READ GRAPHICS PIXEL */
1177         /* Not in graphics mode, can ignore w/o error */
1178         FIXME("Read Graphics Pixel - Not Supported\n");
1179         break;
1180 
1181     case 0x0e: /* TELETYPE OUTPUT */
1182         TRACE("Teletype Output\n");
1183         DOSVM_PutChar(AL_reg(context));
1184         break;
1185 
1186     case 0x0f: /* GET CURRENT VIDEO MODE */
1187         TRACE("Get current video mode: -> mode %d, columns %d\n", data->VideoMode, data->VideoColumns);
1188         /* Note: This should not be a constant value. */
1189         SET_AL( context, data->VideoMode );
1190         SET_AH( context, data->VideoColumns );
1191         SET_BH( context, 0 ); /* Display page 0 */
1192         break;
1193 
1194     case 0x10:
1195         switch AL_reg(context) {
1196         case 0x00: /* SET SINGLE PALETTE REGISTER - A.C. */
1197             TRACE("Set Single Palette Register - Reg 0x0%x Value 0x0%x\n",
1198                 BL_reg(context),BH_reg(context));
1199                 /* BH is the value  BL is the register */
1200                 VGA_SetColor16((int)BL_reg(context),(int)BH_reg(context));
1201             break;
1202         case 0x01: /* SET BORDER (OVERSCAN) */
1203             /* Text terminals have no overscan */
1204             /* I'm setting it anyway. - A.C.   */
1205             TRACE("Set Border (Overscan) - Ignored but set.\n");
1206             VGA_SetColor16(16,(int)BH_reg(context));
1207             break;
1208         case 0x02: /* SET ALL PALETTE REGISTERS - A.C.*/
1209             TRACE("Set all palette registers\n");
1210                 /* ES:DX points to a 17 byte table of colors */
1211                 /* No return data listed */
1212                 /* I'll have to update my table and the default palette */
1213                VGA_Set16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1214             break;
1215         case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
1216             FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
1217             break;
1218         case 0x07: /* GET INDIVIDUAL PALETTE REGISTER  - A.C.*/
1219             TRACE("Get Individual Palette Register 0x0%x\n",BL_reg(context));
1220                 /* BL is register to read [ 0-15 ] BH is return value */
1221                 SET_BH( context, VGA_GetColor16((int)BL_reg(context)) );
1222             break;
1223         case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER  - A.C. */
1224             TRACE("Read Overscan (Border Color) Register\n");
1225                 SET_BH( context, VGA_GetColor16(16) );
1226             break;
1227         case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER - A.C.*/
1228             TRACE("Read All Palette Registers and Overscan Register\n");
1229                 /* ES:DX points to a 17 byte table where the results */
1230                 /*  of this call should be stored.                   */
1231                VGA_Get16Palette(CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edx));
1232             break;
1233         case 0x10: /* SET INDIVIDUAL DAC REGISTER */
1234             {
1235                 PALETTEENTRY paldat;
1236 
1237                 TRACE("Set Individual DAC register\n");
1238                 paldat.peRed   = DH_reg(context);
1239                 paldat.peGreen = CH_reg(context);
1240                 paldat.peBlue  = CL_reg(context);
1241                 paldat.peFlags = 0;
1242                 VGA_SetPalette(&paldat,BX_reg(context)&0xFF,1);
1243             }
1244             break;
1245         case 0x12: /* SET BLOCK OF DAC REGISTERS */
1246             {
1247                 int i;
1248                 PALETTEENTRY paldat;
1249                 BYTE *pt;
1250 
1251                 TRACE("Set Block of DAC registers\n");
1252                 pt = CTX_SEG_OFF_TO_LIN(context,context->SegEs,context->Edx);
1253                 for (i=0;i<CX_reg(context);i++)
1254                 {
1255                     paldat.peRed   = (*(pt+i*3+0)) << 2;
1256                     paldat.peGreen = (*(pt+i*3+1)) << 2;
1257                     paldat.peBlue  = (*(pt+i*3+2)) << 2;
1258                     paldat.peFlags = 0;
1259                     VGA_SetPalette(&paldat,(BX_reg(context)+i)&0xFF,1);
1260                 }
1261             }
1262             break;
1263         case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
1264             FIXME("Select video DAC color page - Not Supported\n");
1265             break;
1266         case 0x15: /* READ INDIVIDUAL DAC REGISTER */
1267             FIXME("Read individual DAC register - Not Supported\n");
1268             break;
1269         case 0x17: /* READ BLOCK OF DAC REGISTERS */
1270             FIXME("Read block of DAC registers - Not Supported\n");
1271             break;
1272         case 0x18: /* SET PEL MASK */
1273             FIXME("Set PEL mask - Not Supported\n");
1274             break;
1275         case 0x19: /* READ PEL MASK */
1276             FIXME("Read PEL mask - Not Supported\n");
1277             break;
1278         case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
1279             FIXME("Get video DAC color page state - Not Supported\n");
1280             break;
1281         case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
1282             FIXME("Perform Gray-scale summing - Not Supported\n");
1283             break;
1284         default:
1285             FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
1286                AL_reg(context));
1287             break;
1288         }
1289         break;
1290 
1291     case 0x11: /* TEXT MODE CHARGEN */
1292         /* Note that second subfunction is *almost* identical. */
1293         /* See INTERRUPT.A for details. */
1294         switch AL_reg(context) {
1295         case 0x00: /* LOAD USER SPECIFIED PATTERNS */
1296         case 0x10:
1297             FIXME("Load User Specified Patterns - Not Supported\n");
1298             break;
1299         case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
1300         case 0x11:
1301             FIXME("Load ROM Monochrome Patterns - Not Supported\n");
1302             break;
1303         case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
1304         case 0x12:
1305             FIXME(
1306                 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
1307             break;
1308         case 0x03: /* SET BLOCK SPECIFIER */
1309             FIXME("Set Block Specifier - Not Supported\n");
1310             break;
1311         case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
1312         case 0x14:
1313             FIXME("Load ROM 8x16 Character Set - Not Supported\n");
1314             break;
1315         case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
1316             FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
1317             break;
1318         case 0x21: /* SET USER GRAPICS CHARACTERS */
1319             FIXME("Set User Graphics Characters - Not Supported\n");
1320             break;
1321         case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
1322             FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
1323             break;
1324         case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
1325             FIXME(
1326                 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
1327             break;
1328         case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
1329             FIXME("Load 8x16 Graphic Chars - Not Supported\n");
1330             break;
1331         case 0x30: /* GET FONT INFORMATION */
1332             FIXME("Get Font Information - Not Supported\n");
1333             break;
1334         default:
1335             FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1336                AL_reg(context));
1337             break;
1338         }
1339         break;
1340 
1341     case 0x12: /* ALTERNATE FUNCTION SELECT */
1342         switch BL_reg(context) {
1343         case 0x10: /* GET EGA INFO */
1344             TRACE("EGA info requested\n");
1345             SET_BH( context, 0x00 );   /* Color screen */
1346             SET_BL( context, data->ModeOptions >> 5 ); /* EGA memory size */
1347             SET_CX( context, data->FeatureBitsSwitches );
1348             break;
1349         case 0x20: /* ALTERNATE PRTSC */
1350             FIXME("Install Alternate Print Screen - Not Supported\n");
1351             break;
1352         case 0x30: /* SELECT VERTICAL RESOLUTION */
1353             FIXME("Select vertical resolution - not supported\n");
1354             break;
1355         case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
1356             FIXME("Default palette loading - not supported\n");
1357             data->VGASettings =
1358                 (data->VGASettings & 0xf7) |
1359                 ((AL_reg(context) == 1) << 3);
1360             break;
1361         case 0x32: /* ENABLE/DISABLE VIDEO ADDRESSING */
1362             FIXME("Video Addressing - Not Supported\n");
1363             break;
1364         case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
1365             FIXME("Gray Scale Summing - Not Supported\n");
1366             break;
1367         case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
1368             TRACE("Set cursor emulation to %d\n", AL_reg(context));
1369             data->ModeOptions =
1370                 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
1371             break;
1372         case 0x36: /* VIDEO ADDRESS CONTROL */
1373             FIXME("Video Address Control - Not Supported\n");
1374             break;
1375         default:
1376             FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
1377                AL_reg(context));
1378             break;
1379         }
1380         break;
1381 
1382     case 0x13: /* WRITE STRING */
1383         /* This one does not imply that string be at cursor. */
1384         FIXME("Write String - Not Supported\n");
1385         break;
1386 
1387     case 0x1a:
1388         switch AL_reg(context) {
1389         case 0x00: /* GET DISPLAY COMBINATION CODE */
1390             TRACE("Get Display Combination Code\n");
1391             SET_AL( context, 0x1a );      /* Function supported */
1392             SET_BL( context, INT10_DCC ); /* Active display */
1393             SET_BH( context, 0x00 );      /* No alternate display */
1394             break;
1395         case 0x01: /* SET DISPLAY COMBINATION CODE */
1396             FIXME("Set Display Combination Code - Not Supported\n");
1397             break;
1398         default:
1399             FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
1400                AL_reg(context));
1401             break;
1402         }
1403     break;
1404 
1405     case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
1406         TRACE("Get functionality/state information\n");
1407         if (BX_reg(context) == 0x0000)
1408         {
1409             BYTE *ptr = CTX_SEG_OFF_TO_LIN(context,
1410                                            context->SegEs, 
1411                                            context->Edi);
1412             SET_AL( context, 0x1b ); /* Function is supported */
1413             INT10_FillStateInformation( ptr, data );
1414         }
1415         break;
1416 
1417     case 0x1c: /* SAVE/RESTORE VIDEO STATE */
1418         FIXME("Save/Restore Video State - Not Supported\n");
1419         break;
1420 
1421         case 0xef:  /* get video mode for hercules-compatibles   */
1422                     /* There's no reason to really support this  */
1423                     /* is there?....................(A.C.)       */
1424                 TRACE("Just report the video not hercules compatible\n");
1425                 SET_DX( context, 0xffff );
1426                 break;
1427 
1428     case 0x4f: /* VESA */
1429         INT10_HandleVESA(context);
1430         break;
1431 
1432     case 0xfe: /* GET SHADOW BUFFER */
1433         TRACE( "GET SHADOW BUFFER %x:%x - ignored\n",
1434                context->SegEs, DI_reg(context) );
1435         break;
1436 
1437     default:
1438         FIXME("Unknown - 0x%x\n", AH_reg(context));
1439         INT_BARF( context, 0x10 );
1440     }
1441 }
1442 
1443 
1444 /**********************************************************************
1445  *         DOSVM_PutChar
1446  *
1447  * Write single character to VGA console at the current 
1448  * cursor position and updates the BIOS cursor position.
1449  */
1450 void DOSVM_PutChar( BYTE ascii )
1451 {
1452   BIOSDATA *data = DOSVM_BiosData();
1453   unsigned  xpos, ypos;
1454 
1455   TRACE("char: 0x%02x(%c)\n", ascii, ascii);
1456 
1457   INT10_InitializeVideoMode( data );
1458 
1459   VGA_PutChar( ascii );
1460   VGA_GetCursorPos( &xpos, &ypos );
1461   INT10_SetCursorPos( data, 0, xpos, ypos );
1462 }
1463 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.