Revert 16bit win95 version back to original value. Fixes InstallShield
[wine] / msdos / int10.c
1 /*
2  * BIOS interrupt 10h handler
3  */
4
5 #include <stdlib.h>
6 #include "miscemu.h"
7 #include "vga.h"
8 #include "debugtools.h"
9 #include "console.h"
10
11 DEFAULT_DEBUG_CHANNEL(int10);
12
13 static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
14        int *wattribute);
15 static void scroll_window(int direction, char lines, char row1, 
16    char col1, char row2, char col2, char attribute);
17
18 static int color_palette[16];
19
20 #define SCROLL_UP 1
21 #define SCROLL_DOWN 2
22
23 /* FIXME: is row or column first? */
24 static void BIOS_GetCursorPos(BIOSDATA*data,unsigned page,unsigned*X,unsigned*Y)
25 {
26   *X = data->VideoCursorPos[page*2];
27   *Y = data->VideoCursorPos[page*2+1];
28 }
29
30 static void BIOS_SetCursorPos(BIOSDATA*data,unsigned page,unsigned X,unsigned Y)
31 {
32   data->VideoCursorPos[page*2] = X;
33   data->VideoCursorPos[page*2+1] = Y;
34 }
35
36 /**********************************************************************
37  *          INT_Int10Handler (WPROCS.116)
38  *
39  * Handler for int 10h (video).
40  * 
41  * NOTE:
42  *    Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
43  *    are present in this list. (SVGA and XGA are not) That is not
44  *    to say that all these functions should be supported, but if
45  *    anyone is brain-damaged enough to want to emulate one of these
46  *    beasts then this should get you started. 
47  *
48  * NOTE:
49  *    Several common graphical extensions used by Microsoft hook
50  *    off of here. I have *not* added them to this list (yet). They
51  *    include:
52  *
53  *    MSHERC.COM - More functionality for Hercules cards.
54  *    EGA.SYS (also MOUSE.COM) - More for EGA cards.
55  *    
56  *    Yes, MS also added this support into their mouse driver. Don't
57  *    ask me, I don't work for them.
58  *
59  * Joseph Pranevich - 9/98 
60  *
61  *  Jess Haas 2/99
62  *      Added support for Vesa. It is not complete but is a start. 
63  *      NOTE: Im not sure if i did all this right or if eny of it works.
64  *      Currently i dont have a program that uses Vesa that actually gets far 
65  *      enough without crashing to do vesa stuff.
66  * 
67  *      Added additional vga graphic support - 3/99
68  */
69
70 void WINAPI INT_Int10Handler( CONTEXT86 *context )
71 {
72     static int registered_colors = FALSE;
73     BIOSDATA *data = DOSMEM_BiosData();
74
75     if (!registered_colors)
76     {
77         /* Colors:
78              0000b   black          1000b   dark gray
79              0001b   blue           1001b   light blue
80              0010b   green          1010b   light green
81              0011b   cyan           1011b   light cyan
82              0100b   red            1100b   light red
83              0101b   magenta        1101b   light magenta
84              0110b   brown          1110b   yellow
85              0111b   light gray     1111b   white
86         */
87         
88         /* These AllocColor calls have the side-effect of triggering 
89            terminal initialization as xx_Init() is no longer called on
90            startup. Which is what we want anyway. */
91
92         color_palette[0]  = CONSOLE_AllocColor(WINE_BLACK);
93         color_palette[1]  = CONSOLE_AllocColor(WINE_BLUE);
94         color_palette[2]  = CONSOLE_AllocColor(WINE_GREEN);
95         color_palette[3]  = CONSOLE_AllocColor(WINE_CYAN);
96         color_palette[4]  = CONSOLE_AllocColor(WINE_RED);
97         color_palette[5]  = CONSOLE_AllocColor(WINE_MAGENTA);
98         color_palette[6]  = CONSOLE_AllocColor(WINE_BROWN);
99         color_palette[7]  = CONSOLE_AllocColor(WINE_LIGHT_GRAY);
100         color_palette[8]  = CONSOLE_AllocColor(WINE_DARK_GRAY);
101         color_palette[9]  = CONSOLE_AllocColor(WINE_LIGHT_BLUE);
102         color_palette[10] = CONSOLE_AllocColor(WINE_LIGHT_GREEN);
103         color_palette[11] = CONSOLE_AllocColor(WINE_LIGHT_CYAN);
104         color_palette[12] = CONSOLE_AllocColor(WINE_LIGHT_RED);
105         color_palette[13] = CONSOLE_AllocColor(WINE_LIGHT_MAGENTA);
106         color_palette[14] = CONSOLE_AllocColor(WINE_YELLOW);
107         color_palette[15] = CONSOLE_AllocColor(WINE_WHITE);
108
109         registered_colors = TRUE;
110     }
111
112     if(AL_reg(context) == 0x4F) { /* VESA functions */
113         switch(AH_reg(context)) {
114
115         case 0x00: /* GET SuperVGA INFORMATION */
116             FIXME("Vesa Get SuperVGA Info STUB!\n");
117             AL_reg(context) = 0x4f;
118             AH_reg(context) = 0x01; /* 0x01=failed 0x00=succesful */
119             break;
120         case 0x01: /* GET SuperVGA MODE INFORMATION */
121             FIXME("VESA GET SuperVGA Mode Information - Not supported\n");
122             AL_reg(context) = 0x4f;
123             AH_reg(context) = 0x01; /* 0x00 = successful 0x01 = failed */
124             break;
125         case 0x02: /* SET SuperVGA VIDEO MODE */
126             switch(BX_reg(context)) {
127                 /* OEM Video Modes */
128                 case 0x00: /* 40x25 */
129                 case 0x01:
130                         TRACE("Set VESA Text Mode - 0x0%x\n",
131                            BX_reg(context));
132                         VGA_SetAlphaMode(40, 25);
133                         data->VideoColumns = 40;
134                         break;                
135                 case 0x02:
136                 case 0x03:
137                 case 0x07:
138                     TRACE("Set VESA Text Mode - 0x0%x\n",
139                        BX_reg(context));
140                     VGA_SetAlphaMode(80, 25);
141                     data->VideoColumns = 80;
142                     break;
143                 case 0x0D:
144                     TRACE("Setting VESA 320x200 16-color mode\n");
145                     VGA_SetMode(320,200,4);
146                     break;
147                 case 0x0E:
148                     TRACE("Setting VESA 640x200 16-color mode\n");
149                     VGA_SetMode(640,200,4); 
150                     break;
151                 case 0x10:
152                     TRACE("Setting VESA 640x350 16-color mode\n");
153                     VGA_SetMode(640,350,4);
154                     break;
155                 case 0x12:
156                     TRACE("Setting VESA 640x480 16-color mode\n");
157                     VGA_SetMode(640,480,4);
158                     break;
159                 case 0x13:
160                     TRACE("Setting VESA 320x200 256-color mode\n");
161                     VGA_SetMode(320,200,8);
162                     break;
163                 /* VBE Modes */
164                 case 0x100:
165                     TRACE("Setting VESA 640x400 256-color mode\n");
166                     VGA_SetMode(640,400,8);
167                     break;
168                 case 0x101:
169                     TRACE("Setting VESA 640x480 256-color mode\n");
170                     VGA_SetMode(640,480,8);
171                     break;
172                 case 0x102:
173                     TRACE("Setting VESA 800x600 16-color mode\n");
174                     VGA_SetMode(800,600,4);
175                     break;
176                 case 0x103:
177                     TRACE("Setting VESA 800x600 256-color mode\n");
178                     VGA_SetMode(800,600,8);
179                     break;
180                 case 0x104:
181                     TRACE("Setting VESA 1024x768 16-color mode\n");
182                     VGA_SetMode(1024,768,4);
183                     break;
184                 case 0x105:
185                     TRACE("Setting VESA 1024x768 256-color mode\n");
186                     VGA_SetMode(1024,768,8);
187                     break;
188                 case 0x106:
189                     TRACE("Setting VESA 1280x1024 16-color mode\n");
190                     VGA_SetMode(1280,1024,4);
191                     break;
192                 case 0x107:
193                     TRACE("Setting VESA 1280x1024 256-color mode\n");
194                     VGA_SetMode(1280,1024,8);
195                     break;
196                 /* 108h - 10Ch are text modes and im lazy so :p */
197                 /* VBE v1.2+ */
198                 case 0x10D:
199                     TRACE("Setting VESA 320x200 15bpp\n");
200                     VGA_SetMode(320,200,15);
201                     break;
202                 case 0x10E:
203                     TRACE("Setting VESA 320x200 16bpp\n");
204                     VGA_SetMode(320,200,16);
205                     break;
206                 case 0x10F:
207                     TRACE("Setting VESA 320x200 24bpp\n");
208                     VGA_SetMode(320,200,24);
209                     break;
210                 case 0x110:
211                     TRACE("Setting VESA 640x480 15bpp\n");
212                     VGA_SetMode(640,480,15);
213                     break;
214                 case 0x111:
215                     TRACE("Setting VESA 640x480 16bpp\n");
216                     VGA_SetMode(640,480,16);
217                     break;
218                 case 0x112:
219                     TRACE("Setting VESA 640x480 24bpp\n");
220                     VGA_SetMode(640,480,24);
221                     break;
222                 case 0x113:
223                     TRACE("Setting VESA 800x600 15bpp\n");
224                     VGA_SetMode(800,600,15);
225                     break;
226                 case 0x114:
227                     TRACE("Setting VESA 800x600 16bpp\n");
228                     VGA_SetMode(800,600,16);
229                     break;
230                 case 0x115:
231                     TRACE("Setting VESA 800x600 24bpp\n");
232                     VGA_SetMode(800,600,24);
233                     break;
234                 case 0x116:
235                     TRACE("Setting VESA 1024x768 15bpp\n");
236                     VGA_SetMode(1024,768,15);
237                     break;
238                 case 0x117:
239                     TRACE("Setting VESA 1024x768 16bpp\n");
240                     VGA_SetMode(1024,768,16);
241                     break;
242                 case 0x118:
243                     TRACE("Setting VESA 1024x768 24bpp\n");
244                     VGA_SetMode(1024,768,24);
245                     break;
246                 case 0x119:
247                     TRACE("Setting VESA 1280x1024 15bpp\n");
248                     VGA_SetMode(1280,1024,15);
249                     break;
250                 case 0x11A:
251                     TRACE("Setting VESA 1280x1024 16bpp\n");
252                     VGA_SetMode(1280,1024,16);
253                     break;
254                 case 0x11B:
255                     TRACE("Setting VESA 1280x1024 24bpp\n");
256                     VGA_SetMode(1280,1024,24);
257                     break;
258                 default:
259                     FIXME("VESA Set Video Mode (0x%x) - Not Supported\n", BX_reg(context));
260             }
261             data->VideoMode = BX_reg(context);
262             AL_reg(context) = 0x4f;
263             AH_reg(context) = 0x00;
264             break;      
265         case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
266                 AL_reg(context) = 0x4f;
267                 AH_reg(context) = 0x00; /* should probly check if a vesa mode has ben set */
268                 BX_reg(context) = data->VideoMode;
269                 break;
270         case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
271                 ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
272                 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */      
273                 /* maybe we should do this instead ? */
274                 /* AH_reg(context = 0x01;  not implemented so just fail */
275                 break;
276         case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
277                 ERR("VESA CPU VIDEO MEMORY CONTROL\n");
278                 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */      
279                 /* maybe we should do this instead ? */
280                 /* AH_reg(context = 0x001; not implemented so just fail */
281                 break;
282         case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
283                 ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
284                 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */      
285                 /* maybe we should do this instead ? */
286                 /* AH_reg(context = 0x001; not implemented so just fail */
287                 break;
288         case 0x07: /* GET/SET DISPLAY START */
289                 ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
290                 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */      
291                 /* maybe we should do this instead ? */
292                 /* AH_reg(context = 0x001; not implemented so just fail */
293                 break;
294         case 0x08: /* GET/SET DAC PALETTE CONTROL */
295                 ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
296                 /* AL_reg(context) = 0x4f; = supported so not set since not implemented */      
297                 /* maybe we should do this instead ? */
298                 /* AH_reg(context = 0x001; not implemented so just fail */
299                 break;
300         case 0x09: /* SET PALETTE ENTRIES */
301                 FIXME("VESA Set palette entries - not implemented\n");
302                 break;
303         case 0xef:  /* get video mode for hercules-compatibles   */
304                     /* There's no reason to really support this  */
305                     /* is there?....................(A.C.)       */
306                 TRACE("Just report the video not hercules compatible\n");
307                 DX_reg(context) = 0xffff;
308                 break; 
309         case 0xff: /* Turn VESA ON/OFF */
310                 /* i dont know what to do */
311                 break;
312         default:
313                 FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
314                 break;          
315         }
316     }
317     else {
318
319     switch(AH_reg(context)) {
320
321     case 0x00: /* SET VIDEO MODE */
322         /* Text Modes: */
323         /* (mode) (text rows/cols)
324             0x00 - 40x25 
325             0x01 - 40x25
326             0x02 - 80x25
327             0x03 - 80x25 or 80x43 or 80x50 (assume 80x25) 
328             0x07 - 80x25
329         */
330
331         switch (AL_reg(context)) {
332             case 0x00: /* 40x25 */
333             case 0x01:
334                 VGA_Exit();
335                 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
336                    AL_reg(context));
337                 VGA_SetAlphaMode(40, 25);
338                 data->VideoColumns = 40;
339                 break;                
340             case 0x02:
341             case 0x03:
342             case 0x07:
343                 VGA_Exit();
344                 TRACE("Set Video Mode - Set to Text - 0x0%x\n",
345                    AL_reg(context));
346                 VGA_SetAlphaMode(80, 25);
347                 data->VideoColumns = 80;
348                 break;
349             case 0x0D:
350                 TRACE("Setting VGA 320x200 16-color mode\n");
351                 VGA_SetMode(320,200,4);
352                 break;
353             case 0x0E:
354                 TRACE("Setting VGA 640x200 16-color mode\n");
355                 VGA_SetMode(640,200,4); 
356                 break;
357             case 0x10:
358                 TRACE("Setting VGA 640x350 16-color mode\n");
359                 VGA_SetMode(640,350,4);
360                 break;
361             case 0x12:
362                 TRACE("Setting VGA 640x480 16-color mode\n");
363                 VGA_SetMode(640,480,4);
364                 break;
365             case 0x13:
366                 TRACE("Setting VGA 320x200 256-color mode\n");
367                 VGA_SetMode(320,200,8);
368                 break;
369             default:
370                 FIXME("Set Video Mode (0x%x) - Not Supported\n", 
371                    AL_reg(context));
372         }
373         data->VideoMode = AL_reg(context);
374         break;
375
376     case 0x01: /* SET CURSOR SHAPE */
377         FIXME("Set Cursor Shape - Not Supported\n");
378         break;
379     
380     case 0x02: /* SET CURSOR POSITION */
381         /* BH = Page Number */ /* Not supported */
382         /* DH = Row */ /* 0 is left */
383         /* DL = Column */ /* 0 is top */
384         BIOS_SetCursorPos(data,BH_reg(context),DL_reg(context),DH_reg(context));
385         if (BH_reg(context))
386         {
387            FIXME("Set Cursor Position: Cannot set to page %d\n",
388               BH_reg(context));
389         }
390         else
391         {
392            VGA_SetCursorPos(DL_reg(context), DH_reg(context));
393            TRACE("Set Cursor Position: %d %d\n", DH_reg(context), 
394               DL_reg(context));
395         }
396         break;
397
398     case 0x03: /* GET CURSOR POSITION AND SIZE */
399         {
400           unsigned row, col;
401
402           TRACE("Get cursor position and size (page %d)\n", BH_reg(context));
403           CX_reg(context) = data->VideoCursorType;
404           BIOS_GetCursorPos(data,BH_reg(context),&col,&row);
405           DH_reg(context) = row;
406           DL_reg(context) = col;
407           TRACE("Cursor Position: %d %d\n", DH_reg(context), DL_reg(context));
408         }
409         break;
410
411     case 0x04: /* READ LIGHT PEN POSITION */
412         FIXME("Read Light Pen Position - Not Supported\n");
413         AH_reg(context) = 0x00; /* Not down */
414         break;
415
416     case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
417         FIXME("Select Active Display Page - Not Supported\n");
418         data->VideoCurPage = AL_reg(context);
419         break;
420
421     case 0x06: /* SCROLL UP WINDOW */
422         /* AL = Lines to scroll */
423         /* BH = Attribute */
424         /* CH,CL = row, col upper-left */
425         /* DH,DL = row, col lower-right */
426         scroll_window(SCROLL_UP, AL_reg(context), CH_reg(context), 
427            CL_reg(context), DH_reg(context), DL_reg(context), 
428            BH_reg(context));
429         TRACE("Scroll Up Window %d\n", AL_reg(context));
430         break;
431
432     case 0x07: /* SCROLL DOWN WINDOW */
433         /* AL = Lines to scroll */
434         /* BH = Attribute */
435         /* CH,CL = row, col upper-left */
436         /* DH,DL = row, col lower-right */
437         scroll_window(SCROLL_DOWN, AL_reg(context), CH_reg(context), 
438            CL_reg(context), DH_reg(context), DL_reg(context), 
439            BH_reg(context));
440         TRACE("Scroll Down Window %d\n", AL_reg(context));
441         break;
442
443     case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
444         {
445             /* Note here that color data returned is bogus, will fix later. */
446             char ch;
447             int bg, fg, attr;
448             if (BH_reg(context)) /* Write to different page */
449             {
450                 FIXME("Read character and attribute at cursor position -"
451                       " Can't read from non-0 page\n");
452                 AL_reg(context) = ' '; /* That page is blank */
453                 AH_reg(context) = 7;
454             }
455             else
456             {
457                 TRACE(
458                       "Read Character and Attribute at Cursor Position\n");
459                 CONSOLE_GetCharacterAtCursor(&ch, &fg, &bg, &attr);
460                 AL_reg(context) = ch;
461                 AH_reg(context) = 7;    /* FIXME: We're assuming wh on bl */ 
462             }
463         }
464         break;
465
466     case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
467     case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */ 
468        /* AL = Character to display. */
469        /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
470        /* BL = Attribute / Color */
471        /* CX = Times to Write Char */
472        /* Note here that the cursor is not advanced. */
473        {
474            unsigned row, col;
475
476            BIOS_GetCursorPos(data,BH_reg(context),&col,&row);
477            VGA_WriteChars(col, row,
478                           AL_reg(context),
479                           (AH_reg(context) == 0x09) ? BL_reg(context) : -1,
480                           CX_reg(context));
481            if (CX_reg(context) > 1)
482               TRACE("Write Character%s at Cursor Position (Rep. %d): %c\n",
483                     (AH_reg(context) == 0x09) ? " and Attribute" : "",
484                  CX_reg(context), AL_reg(context));
485            else
486               TRACE("Write Character%s at Cursor Position: %c\n",
487                     (AH_reg(context) == 0x09) ? " and Attribute" : "",
488                 AL_reg(context));
489        }
490        break;
491
492     case 0x0b: 
493         switch BH_reg(context) {
494         case 0x00: /* SET BACKGROUND/BORDER COLOR */
495             /* In text modes, this sets only the border... */
496             /* According to the interrupt list and one of my books. */
497             /* Funny though that Beyond Zork seems to indicate that it 
498                also sets up the default background attributes for clears
499                and scrolls... */
500             /* Bear in mind here that we do not want to change,
501                apparantly, the foreground or attribute of the background
502                with this call, so we should check first to see what the
503                foreground already is... FIXME */
504             TRACE("Set Background/Border Color: %d\n", 
505                BL_reg(context));
506             CONSOLE_SetBackgroundColor(color_palette[0],
507                color_palette[BL_reg(context)]);   
508             break;
509         case 0x01: /* SET PALETTE */
510             FIXME("Set Palette - Not Supported\n");
511             break;
512         default:
513             FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n", 
514                BH_reg(context));
515             break;
516         }
517         break;
518
519     case 0x0c: /* WRITE GRAPHICS PIXEL */
520         /* Not in graphics mode, can ignore w/o error */
521         FIXME("Write Graphics Pixel - Not Supported\n");
522         break;
523         
524     case 0x0d: /* READ GRAPHICS PIXEL */
525         /* Not in graphics mode, can ignore w/o error */
526         FIXME("Read Graphics Pixel - Not Supported\n");
527         break;
528               
529     case 0x0e: /* TELETYPE OUTPUT */
530         TRACE("Teletype Output\n");
531         CONSOLE_Write(AL_reg(context), 0, 0, 0);
532         break;
533
534     case 0x0f: /* GET CURRENT VIDEO MODE */
535         TRACE("Get current video mode\n");
536         /* Note: This should not be a constant value. */
537         AL_reg(context) = data->VideoMode;
538         AH_reg(context) = data->VideoColumns;
539         BH_reg(context) = 0; /* Display page 0 */
540         break;
541
542     case 0x10: 
543         switch AL_reg(context) {
544         case 0x00: /* SET SINGLE PALETTE REGISTER */
545             FIXME("Set Single Palette Register - Not Supported\n");
546             break;
547         case 0x01: /* SET BORDER (OVERSCAN) */
548             /* Text terminals have no overscan */
549             TRACE("Set Border (Overscan) - Ignored\n");
550             break;
551         case 0x02: /* SET ALL PALETTE REGISTERS */
552             FIXME("Set all palette registers - Not Supported\n");
553             break;
554         case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
555             FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
556             break;
557         case 0x07: /* GET INDIVIDUAL PALETTE REGISTER */
558             FIXME("Get Individual Palette Register - Not Supported\n");
559             break;
560         case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
561             FIXME(
562                "Read Overscan (Border Color) Register - Not Supported\n");
563             break;
564         case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
565             FIXME(
566                "Read All Palette Registers and Overscan Register "
567                " - Not Supported\n");
568             break;
569         case 0x10: /* SET INDIVIDUAL DAC REGISTER */
570             FIXME("Set Individual DAC register - Not Supported\n");
571             break;
572         case 0x12: /* SET BLOCK OF DAC REGISTERS */
573             FIXME("Set Block of DAC registers - Not Supported\n");
574             break;
575         case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
576             FIXME("Select video DAC color page - Not Supported\n");
577             break;
578         case 0x15: /* READ INDIVIDUAL DAC REGISTER */
579             FIXME("Read individual DAC register - Not Supported\n");
580             break;
581         case 0x17: /* READ BLOCK OF DAC REGISTERS */
582             FIXME("Read block of DAC registers - Not Supported\n");
583             break;
584         case 0x18: /* SET PEL MASK */
585             FIXME("Set PEL mask - Not Supported\n");
586             break;
587         case 0x19: /* READ PEL MASK */
588             FIXME("Read PEL mask - Not Supported\n");
589             break;
590         case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
591             FIXME("Get video DAC color page state - Not Supported\n");
592             break;
593         case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
594             FIXME("Perform Gray-scale summing - Not Supported\n");
595             break;
596         default:
597             FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n", 
598                AL_reg(context));
599             break;
600         }
601         break;
602
603     case 0x11: /* TEXT MODE CHARGEN */
604         /* Note that second subfunction is *almost* identical. */
605         /* See INTERRUPT.A for details. */
606         switch AL_reg(context) {
607         case 0x00: /* LOAD USER SPECIFIED PATTERNS */
608         case 0x10:
609             FIXME("Load User Specified Patterns - Not Supported\n");
610             break;
611         case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
612         case 0x11:
613             FIXME("Load ROM Monochrome Patterns - Not Supported\n");
614             break;
615         case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
616         case 0x12:
617             FIXME(
618                 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");       
619             break;
620         case 0x03: /* SET BLOCK SPECIFIER */
621             FIXME("Set Block Specifier - Not Supported\n");
622             break;
623         case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
624         case 0x14:
625             FIXME("Load ROM 8x16 Character Set - Not Supported\n");
626             break;
627         case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
628             FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
629             break;
630         case 0x21: /* SET USER GRAPICS CHARACTERS */
631             FIXME("Set User Graphics Characters - Not Supported\n");
632             break;
633         case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
634             FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
635             break;
636         case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
637             FIXME(
638                 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
639             break;
640         case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
641             FIXME("Load 8x16 Graphic Chars - Not Supported\n");
642             break;
643         case 0x30: /* GET FONT INFORMATION */
644             FIXME("Get Font Information - Not Supported\n");
645             break;
646         default:
647             FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
648                AL_reg(context));
649             break;
650         }
651         break;
652         
653     case 0x12: /* ALTERNATE FUNCTION SELECT */
654         switch BL_reg(context) {
655         case 0x10: /* GET EGA INFO */
656             TRACE("EGA info requested\n");
657             BH_reg(context) = 0x00;   /* Color screen */
658             BL_reg(context) =
659                 data->ModeOptions >> 5; /* EGA memory size */
660             CX_reg(context) =
661                 data->FeatureBitsSwitches;
662             break;
663         case 0x20: /* ALTERNATE PRTSC */
664             FIXME("Install Alternate Print Screen - Not Supported\n");
665             break;
666         case 0x30: /* SELECT VERTICAL RESOULTION */
667             FIXME("Select vertical resolution - not supported\n");
668             break;
669         case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
670             FIXME("Default palette loading - not supported\n");
671             data->VGASettings =
672                 (data->VGASettings & 0xf7) |
673                 ((AL_reg(context) == 1) << 3);
674             break;
675         case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
676             FIXME("Video Addressing - Not Supported\n");
677             break;
678         case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
679             FIXME("Gray Scale Summing - Not Supported\n");
680             break;
681         case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
682             TRACE("Set cursor emulation to %d\n", AL_reg(context));
683             data->ModeOptions =
684                 (data->ModeOptions & 0xfe)|(AL_reg(context) == 1);
685             break;
686         case 0x36: /* VIDEO ADDRESS CONTROL */
687             FIXME("Video Address Control - Not Supported\n");
688             break;
689         default:
690             FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
691                AL_reg(context));
692             break;
693         }
694         break;
695
696     case 0x13: /* WRITE STRING */
697         /* This one does not imply that string be at cursor. */
698         FIXME("Write String - Not Supported\n");
699         break;
700                              
701     case 0x1a: 
702         switch AL_reg(context) {
703         case 0x00: /* GET DISPLAY COMBINATION CODE */
704             TRACE("Get Display Combination Code\n");
705             AX_reg(context) = 0x001a;
706             BL_reg(context) = 0x08; /* VGA w/ color analog display */
707             BH_reg(context) = 0x00; /* No secondary hardware */
708             break;
709         case 0x01: /* SET DISPLAY COMBINATION CODE */
710             FIXME("Set Display Combination Code - Not Supported\n");
711             break;
712         default:
713             FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n", 
714                AL_reg(context));
715             break;
716         }
717     break;
718
719     case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
720         FIXME("Get functionality/state information - partially implemented\n");
721         if (BX_reg(context) == 0x0)
722         {
723           AL_reg(context) = 0x1b;
724           if (ISV86(context)) /* real */
725             context->SegEs = 0xf000;
726           else
727             context->SegEs = DOSMEM_BiosSysSeg;
728           BX_reg(context) = 0xe000;
729         }
730         break;
731
732     case 0x1c: /* SAVE/RESTORE VIDEO STATE */
733         FIXME("Save/Restore Video State - Not Supported\n");
734         break;
735
736     case 0x4f: /* Get SuperVGA INFORMATION */
737         {
738           BYTE *p =
739                CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi);
740           /* BOOL16 vesa20 = (*(DWORD *)p == *(DWORD *)"VBE2"); */
741   
742           TRACE("Get SuperVGA information\n");
743           AH_reg(context) = 0;
744           *(DWORD *)p = *(DWORD *)"VESA";
745           *(WORD *)(p+0x04) = 0x0200; /* VESA 2.0 */
746           *(DWORD *)(p+0x06) = 0x00000000; /* pointer to OEM name */
747           *(DWORD *)(p+0x0a) = 0xfffffffd; /* capabilities flags :-) */
748         }
749         break;
750         case 0xef:  /* get video mode for hercules-compatibles   */
751                     /* There's no reason to really support this  */
752                     /* is there?....................(A.C.)       */
753                 TRACE("Just report the video not hercules compatible\n");
754                 DX_reg(context) = 0xffff;
755                 break; 
756     default:
757         FIXME("Unknown - 0x%x\n", AH_reg(context));
758         INT_BARF( context, 0x10 );
759     }
760     }
761 }
762
763 static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
764    int *wattribute)
765 {
766     /* This is a local function to convert the text-mode attributes
767        to Wine's color and attribute scheme */
768
769     /* Foreground Color is stored in bits 3 through 0 */
770     /* Background Color is stored in bits 6 through 4 */
771     /* If this has bit 7 set, then we need to blink */
772
773     *fg = color_palette[attribute & 15];
774     *bg = color_palette[(attribute & 112) / 16];
775     *wattribute = attribute & 128;
776
777 }
778
779 static void scroll_window(int direction, char lines, char row1, 
780    char col1, char row2, char col2, char attribute)
781 {
782    int wattribute, bg_color, fg_color;
783
784    conv_text_mode_attributes(attribute, &fg_color, &bg_color,
785       &wattribute);
786
787    if (!lines) /* Actually, clear the window */
788    {
789       CONSOLE_ClearWindow(row1, col1, row2, col2, bg_color, wattribute);
790    }
791    else if (direction == SCROLL_UP)
792    {
793       CONSOLE_ScrollUpWindow(row1, col1, row2, col2, lines, bg_color,
794          wattribute);
795    }
796    else
797    {
798       CONSOLE_ScrollDownWindow(row1, col1, row2, col2, lines, bg_color,
799          wattribute);
800    }
801 }
802