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