int10.c 29 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * BIOS interrupt 10h handler
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
5
#include <stdlib.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
6
#include "miscemu.h"
7
#include "vga.h"
8
#include "debugtools.h"
9 10
#include "console.h"

11 12
DEFAULT_DEBUG_CHANNEL(int10)

13 14
static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
       int *wattribute);
15 16 17 18 19
static void write_char_attribute_at_cursor(char output, char page_num, 
       char attribute, short times);
static void scroll_window(int direction, char lines, char row1, 
   char col1, char row2, char col2, char attribute);

20
static int color_palette[16];
21

22 23
#define SCROLL_UP 1
#define SCROLL_DOWN 2
Alexandre Julliard's avatar
Alexandre Julliard committed
24

Alexandre Julliard's avatar
Alexandre Julliard committed
25 26 27 28
/**********************************************************************
 *	    INT_Int10Handler
 *
 * Handler for int 10h (video).
Alexandre Julliard's avatar
Alexandre Julliard committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 * 
 * NOTE:
 *    Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
 *    are present in this list. (SVGA and XGA are not) That is not
 *    to say that all these functions should be supported, but if
 *    anyone is braindamaged enough to want to emulate one of these
 *    beasts then this should get you started. 
 *
 * NOTE:
 *    Several common graphical extensions used by Microsoft hook
 *    off of here. I have *not* added them to this list (yet). They
 *    include:
 *
 *    MSHERC.COM - More functionality for Hercules cards.
 *    EGA.SYS (also MOUSE.COM) - More for EGA cards.
 *    
 *    Yes, MS also added this support into their mouse driver. Don't
 *    ask me, I don't work for them.
 *
 * Joseph Pranevich - 9/98 
Alexandre Julliard's avatar
Alexandre Julliard committed
49
 */
50 51
/*  Jess Haas 2/99
 *	Added support for Vesa. It is not complete but is a start. 
52 53 54
 *	NOTE: Im not sure if i did all this right or if eny of it works.
 *	Currently i dont have a program that uses Vesa that actually gets far 
 *	enough without crashing to do vesa stuff.
55 56
 * 
 *      Added additional vga graphic support - 3/99
57
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
58

59
void WINAPI INT_Int10Handler( CONTEXT86 *context )
Alexandre Julliard's avatar
Alexandre Julliard committed
60
{
61 62 63 64 65 66 67 68 69 70 71 72 73 74
    static int registered_colors = FALSE;

    if (!registered_colors)
    {
        /* Colors:
             0000b   black          1000b   dark gray
             0001b   blue           1001b   light blue
             0010b   green          1010b   light green
             0011b   cyan           1011b   light cyan
             0100b   red            1100b   light red
             0101b   magenta        1101b   light magenta
             0110b   brown          1110b   yellow
             0111b   light gray     1111b   white
        */
75 76 77 78
        
        /* These AllocColor calls have the side-effect of triggering 
           ternimal initialization as xx_Init() is no longer called on
           startup. Which is what we want anyway. */
79

80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        color_palette[0]  = CONSOLE_AllocColor(WINE_BLACK);
        color_palette[1]  = CONSOLE_AllocColor(WINE_BLUE);
        color_palette[2]  = CONSOLE_AllocColor(WINE_GREEN);
        color_palette[3]  = CONSOLE_AllocColor(WINE_CYAN);
        color_palette[4]  = CONSOLE_AllocColor(WINE_RED);
        color_palette[5]  = CONSOLE_AllocColor(WINE_MAGENTA);
        color_palette[6]  = CONSOLE_AllocColor(WINE_BROWN);
        color_palette[7]  = CONSOLE_AllocColor(WINE_LIGHT_GRAY);
        color_palette[8]  = CONSOLE_AllocColor(WINE_DARK_GRAY);
        color_palette[9]  = CONSOLE_AllocColor(WINE_LIGHT_BLUE);
        color_palette[10] = CONSOLE_AllocColor(WINE_LIGHT_GREEN);
        color_palette[11] = CONSOLE_AllocColor(WINE_LIGHT_CYAN);
        color_palette[12] = CONSOLE_AllocColor(WINE_LIGHT_RED);
        color_palette[13] = CONSOLE_AllocColor(WINE_LIGHT_MAGENTA);
        color_palette[14] = CONSOLE_AllocColor(WINE_YELLOW);
        color_palette[15] = CONSOLE_AllocColor(WINE_WHITE);
96 97

        registered_colors = TRUE;
98 99
    }

100 101 102 103
    if(AL_reg(context) == 0x4F) { /* VESA functions */
	switch(AH_reg(context)) {

	case 0x00: /* GET SuperVGA INFORMATION */
104
	    FIXME("Vesa Get SuperVGA Info STUB!\n");
105 106 107 108
	    AL_reg(context) = 0x4f;
	    AH_reg(context) = 0x01; /* 0x01=failed 0x00=succesful */
	    break;
	case 0x01: /* GET SuperVGA MODE INFORMATION */
109
	    FIXME("VESA GET SuperVGA Mode Information - Not supported\n");
110 111 112 113 114 115 116 117 118
	    AL_reg(context) = 0x4f;
	    AH_reg(context) = 0x01; /* 0x00 = successful 0x01 = failed */
	    break;
	case 0x02: /* SET SuperVGA VIDEO MODE */
	    switch(BX_reg(context)) {
	 	/* OEM Video Modes */
		case 0x00: /* 40x25 */
            	case 0x01:
                	VGA_Exit();
119
                	TRACE("Set VESA Text Mode - 0x0%x\n",
120 121 122
                	   BX_reg(context));
                	CONSOLE_ResizeScreen(40, 25);
                	CONSOLE_ClearScreen();
123
                    DOSMEM_BiosData()->VideoColumns = 40;
124 125 126 127 128
                	break;                
            	case 0x02:
            	case 0x03:
            	case 0x07:
            	    VGA_Exit();
129
            	    TRACE("Set VESA Text Mode - 0x0%x\n",
130 131 132
            	       BX_reg(context));
            	    CONSOLE_ResizeScreen(80, 25);
            	    CONSOLE_ClearScreen();
133
                    DOSMEM_BiosData()->VideoColumns = 80;
134
            	    break;
135
	        case 0x0D:
136
                    TRACE("Setting VESA 320x200 16-color mode\n");
137 138 139
                    VGA_SetMode(320,200,4);
                    break;
 	        case 0x0E:
140
                    TRACE("Setting VESA 640x200 16-color mode\n");
141 142 143
                    VGA_SetMode(640,200,4); 
                    break;
	        case 0x10:
144
                    TRACE("Setting VESA 640x350 16-color mode\n");
145 146 147
                    VGA_SetMode(640,350,4);
                    break;
	        case 0x12:
148
                    TRACE("Setting VESA 640x480 16-color mode\n");
149 150 151
                    VGA_SetMode(640,480,4);
                    break;
                case 0x13:
152
            	    TRACE("Setting VESA 320x200 256-color mode\n");
153 154 155 156
            	    VGA_SetMode(320,200,8);
            	    break;
		/* VBE Modes */
		case 0x100:
157
		    TRACE("Setting VESA 640x400 256-color mode\n");
158 159 160
		    VGA_SetMode(640,400,8);
		    break;
		case 0x101:
161
		    TRACE("Setting VESA 640x480 256-color mode\n");
162 163 164
		    VGA_SetMode(640,480,8);
		    break;
		case 0x102:
165
		    TRACE("Setting VESA 800x600 16-color mode\n");
166 167 168
		    VGA_SetMode(800,600,4);
		    break;
		case 0x103:
169
		    TRACE("Setting VESA 800x600 256-color mode\n");
170 171 172
		    VGA_SetMode(800,600,8);
		    break;
		case 0x104:
173
		    TRACE("Setting VESA 1024x768 16-color mode\n");
174 175 176
		    VGA_SetMode(1024,768,4);
		    break;
		case 0x105:
177
		    TRACE("Setting VESA 1024x768 256-color mode\n");
178 179 180
		    VGA_SetMode(1024,768,8);
		    break;
		case 0x106:
181
		    TRACE("Setting VESA 1280x1024 16-color mode\n");
182 183 184
		    VGA_SetMode(1280,1024,4);
		    break;
		case 0x107:
185
		    TRACE("Setting VESA 1280x1024 256-color mode\n");
186 187 188 189 190
		    VGA_SetMode(1280,1024,8);
		    break;
		/* 108h - 10Ch are text modes and im lazy so :p */
		/* VBE v1.2+ */
		case 0x10D:
191
  		    TRACE("Setting VESA 320x200 15bpp\n");
192 193 194
		    VGA_SetMode(320,200,15);
		    break;
		case 0x10E:
195
  		    TRACE("Setting VESA 320x200 16bpp\n");
196 197 198
		    VGA_SetMode(320,200,16);
		    break;
		case 0x10F:
199
  		    TRACE("Setting VESA 320x200 24bpp\n");
200 201 202
		    VGA_SetMode(320,200,24);
		    break;
		case 0x110:
203
  		    TRACE("Setting VESA 640x480 15bpp\n");
204 205 206
		    VGA_SetMode(640,480,15);
		    break;
		case 0x111:
207
  		    TRACE("Setting VESA 640x480 16bpp\n");
208 209 210
		    VGA_SetMode(640,480,16);
		    break;
		case 0x112:
211
  		    TRACE("Setting VESA 640x480 24bpp\n");
212 213 214
		    VGA_SetMode(640,480,24);
		    break;
		case 0x113:
215
 		    TRACE("Setting VESA 800x600 15bpp\n");
216 217 218
		    VGA_SetMode(800,600,15);
		    break;
		case 0x114:
219
 		    TRACE("Setting VESA 800x600 16bpp\n");
220 221 222
		    VGA_SetMode(800,600,16);
		    break;
		case 0x115:
223
 		    TRACE("Setting VESA 800x600 24bpp\n");
224 225 226
		    VGA_SetMode(800,600,24);
		    break;
		case 0x116:
227
 		    TRACE("Setting VESA 1024x768 15bpp\n");
228 229 230
		    VGA_SetMode(1024,768,15);
		    break;
		case 0x117:
231
 		    TRACE("Setting VESA 1024x768 16bpp\n");
232 233 234
		    VGA_SetMode(1024,768,16);
		    break;
		case 0x118:
235
 		    TRACE("Setting VESA 1024x768 24bpp\n");
236 237 238
		    VGA_SetMode(1024,768,24);
		    break;
		case 0x119:
239
 		    TRACE("Setting VESA 1280x1024 15bpp\n");
240 241 242
		    VGA_SetMode(1280,1024,15);
		    break;
		case 0x11A:
243
 		    TRACE("Setting VESA 1280x1024 16bpp\n");
244 245 246
		    VGA_SetMode(1280,1024,16);
		    break;
		case 0x11B:
247
 		    TRACE("Setting VESA 1280x1024 24bpp\n");
248 249 250
		    VGA_SetMode(1280,1024,24);
		    break;
		default:
251
		    FIXME("VESA Set Video Mode (0x%x) - Not Supported\n", BX_reg(context));
252
	    }
253
            DOSMEM_BiosData()->VideoMode = BX_reg(context);
254 255 256 257 258 259
            AL_reg(context) = 0x4f;
	    AH_reg(context) = 0x00;
	    break;	
	case 0x03: /* VESA SuperVGA BIOS - GET CURRENT VIDEO MODE */
		AL_reg(context) = 0x4f;
		AH_reg(context) = 0x00; /* should probly check if a vesa mode has ben set */
260
		BX_reg(context) = DOSMEM_BiosData()->VideoMode;
261 262
		break;
	case 0x04: /* VESA SuperVGA BIOS - SAVE/RESTORE SuperVGA VIDEO STATE */
263
		ERR("VESA SAVE/RESTORE Video State - Not Implemented\n");
264 265 266 267 268
		/* AL_reg(context) = 0x4f; = supported so dont set since not implemented */	
		/* maby we should do this instead ? */
		/* AH_reg(context = 0x01;  not implemented so just fail */
		break;
	case 0x05: /* VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL */
269
		ERR("VESA CPU VIDEO MEMORY CONTROL\n");
270 271 272 273 274
		/* AL_reg(context) = 0x4f; = supported so dont set since not implemented */	
		/* maby we should do this instead ? */
		/* AH_reg(context = 0x001; not implemented so just fail */
		break;
	case 0x06: /* VESA GET/SET LOGICAL SCAN LINE LENGTH */
275
		ERR("VESA GET/SET LOGICAL SCAN LINE LENGTH - Not Implemented\n");
276 277 278 279 280
		/* AL_reg(context) = 0x4f; = supported so dont set since not implemented */	
		/* maby we should do this instead ? */
		/* AH_reg(context = 0x001; not implemented so just fail */
		break;
	case 0x07: /* GET/SET DISPLAY START */
281
		ERR("VESA GET/SET DISPLAY START - Not Implemented\n");
282 283 284 285 286
		/* AL_reg(context) = 0x4f; = supported so dont set since not implemented */	
		/* maby we should do this instead ? */
		/* AH_reg(context = 0x001; not implemented so just fail */
		break;
	case 0x08: /* GET/SET DAC PALETTE CONTROL */
287
		ERR("VESA GET/SET DAC PALETTE CONTROL- Not Implemented\n");
288 289 290 291
		/* AL_reg(context) = 0x4f; = supported so dont set since not implemented */	
		/* maby we should do this instead ? */
		/* AH_reg(context = 0x001; not implemented so just fail */
		break;
292
	case 0x09: /* SET PALETTE ENTRIES */
293
		FIXME("VESA Set palette entries - not implemented\n");
294
		break;
295 296 297 298 299 300
        case 0xef:  /* get video mode for hercules-compatables   */
                    /* There's no reason to really support this  */
                    /* is there?....................(A.C.)       */
                TRACE("Just report the video not hercules compatable\n");
                DX_reg(context) = 0xffff;
                break; 
301 302 303 304
	case 0xff: /* Turn VESA ON/OFF */
		/* i dont know what to do */
		break;
	default:
305
		FIXME("VESA Function (0x%x) - Not Supported\n", AH_reg(context));
306 307 308 309 310
		break;		
	}
}
else {

311
    switch(AH_reg(context)) {
Alexandre Julliard's avatar
Alexandre Julliard committed
312

313
    case 0x00: /* SET VIDEO MODE */
314
        /* Text Modes: */
315 316 317 318
        /* (mode) (text rows/cols)
            0x00 - 40x25 
            0x01 - 40x25
            0x02 - 80x25
319
            0x03 - 80x25 or 80x43 or 80x50 (assume 80x25) 
320 321 322
            0x07 - 80x25
        */

323
        switch (AL_reg(context)) {
324
            case 0x00: /* 40x25 */
325
            case 0x01:
326
                VGA_Exit();
327
                TRACE("Set Video Mode - Set to Text - 0x0%x\n",
328 329 330
                   AL_reg(context));
                CONSOLE_ResizeScreen(40, 25);
                CONSOLE_ClearScreen();
331
                DOSMEM_BiosData()->VideoColumns = 40;
332
                break;                
333 334 335 336
            case 0x02:
            case 0x03:
            case 0x07:
                VGA_Exit();
337
                TRACE("Set Video Mode - Set to Text - 0x0%x\n",
338
                   AL_reg(context));
339
                CONSOLE_ResizeScreen(80, 25);
340
                CONSOLE_ClearScreen();
341
                DOSMEM_BiosData()->VideoColumns = 80;
342
                break;
343
	    case 0x0D:
344
                TRACE("Setting VGA 320x200 16-color mode\n");
345 346 347
                VGA_SetMode(320,200,4);
                break;
	    case 0x0E:
348
                TRACE("Setting VGA 640x200 16-color mode\n");
349 350 351
                VGA_SetMode(640,200,4); 
                break;
	    case 0x10:
352
                TRACE("Setting VGA 640x350 16-color mode\n");
353 354 355
                VGA_SetMode(640,350,4);
                break;
	    case 0x12:
356
                TRACE("Setting VGA 640x480 16-color mode\n");
357 358
                VGA_SetMode(640,480,4);
                break;
359
            case 0x13:
360
                TRACE("Setting VGA 320x200 256-color mode\n");
361 362 363
                VGA_SetMode(320,200,8);
                break;
            default:
364
                FIXME("Set Video Mode (0x%x) - Not Supported\n", 
365
                   AL_reg(context));
366
        }
367
        DOSMEM_BiosData()->VideoMode = AL_reg(context);
Alexandre Julliard's avatar
Alexandre Julliard committed
368 369 370
        break;

    case 0x01: /* SET CURSOR SHAPE */
371
        FIXME("Set Cursor Shape - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
372
        break;
373
    
Alexandre Julliard's avatar
Alexandre Julliard committed
374
    case 0x02: /* SET CURSOR POSITION */
375 376 377 378 379
        /* BH = Page Number */ /* Not supported */
        /* DH = Row */ /* 0 is left */
        /* DL = Column */ /* 0 is top */
        if (BH_reg(context))
        {
380
           FIXME("Set Cursor Position: Cannot set to page %d\n",
381 382 383 384 385
              BH_reg(context));
        }
        else
        {
           CONSOLE_MoveCursor(DH_reg(context), DL_reg(context));
386
           TRACE("Set Cursor Position: %d %d\n", DH_reg(context), 
387 388
              DL_reg(context));
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
389 390 391
        break;

    case 0x03: /* GET CURSOR POSITION AND SIZE */
392 393 394
        {
          CHAR row, col;

395
          FIXME("Get cursor position and size - partially supported\n");
396 397 398 399 400
          CX_reg(context) = 0x0a0b; /* Bogus cursor data */
          CONSOLE_GetCursorPosition(&row, &col);
          DH_reg(context) = row;
          DL_reg(context) = col;
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
401
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
402

Alexandre Julliard's avatar
Alexandre Julliard committed
403
    case 0x04: /* READ LIGHT PEN POSITION */
404
        FIXME("Read Light Pen Position - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
405 406 407 408
        AH_reg(context) = 0x00; /* Not down */
        break;

    case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
409
        FIXME("Select Active Display Page - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
410 411 412
        break;

    case 0x06: /* SCROLL UP WINDOW */
413 414 415 416 417 418 419
        /* AL = Lines to scroll */
        /* BH = Attribute */
        /* CH,CL = row, col upper-left */
        /* DH,DL = row, col lower-right */
        scroll_window(SCROLL_UP, AL_reg(context), CH_reg(context), 
           CL_reg(context), DH_reg(context), DL_reg(context), 
           BH_reg(context));
420
        TRACE("Scroll Up Window %d\n", AL_reg(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
421 422 423
        break;

    case 0x07: /* SCROLL DOWN WINDOW */
424 425 426 427 428 429 430
        /* AL = Lines to scroll */
        /* BH = Attribute */
        /* CH,CL = row, col upper-left */
        /* DH,DL = row, col lower-right */
        scroll_window(SCROLL_DOWN, AL_reg(context), CH_reg(context), 
           CL_reg(context), DH_reg(context), DL_reg(context), 
           BH_reg(context));
431
        TRACE("Scroll Down Window %d\n", AL_reg(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
432 433 434
        break;

    case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
435
        {
436 437 438 439 440
            /* Note here that color data returned is bogus, will fix later. */
            char ch;
            int bg, fg, attr;
            if (BH_reg(context)) /* Write to different page */
            {
441
                FIXME("Read character and attribute at cursor position -"
442 443 444 445 446 447
                      " Can't read from non-0 page\n");
                AL_reg(context) = ' '; /* That page is blank */
                AH_reg(context) = 7;
            }
            else
            {
448
                TRACE(
449 450 451 452 453
                      "Read Character and Attribute at Cursor Position\n");
                CONSOLE_GetCharacterAtCursor(&ch, &fg, &bg, &attr);
                AL_reg(context) = ch;
                AH_reg(context) = 7;	/* FIXME: We're assuming wh on bl */ 
            }
454
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
455 456 457
        break;

    case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
458 459 460 461
       /* AL = Character to display. */
       /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
       /* BL = Attribute / Color */
       /* CX = Times to Write Char */
462
       /* Note here that the cursor is not advanced. */
463 464 465
       write_char_attribute_at_cursor(AL_reg(context), BH_reg(context), 
          BL_reg(context), CX_reg(context));
       if (CX_reg(context) > 1)
466
          TRACE("Write Character and Attribute at Cursor Position "
467 468
             "(Rep. %d) %c\n", CX_reg(context), AL_reg(context));
       else
469
          TRACE("Write Character and Attribute at Cursor"
470 471 472
             "Position: %c\n", AL_reg(context));
       break;

Alexandre Julliard's avatar
Alexandre Julliard committed
473
    case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */ 
474 475 476
       /* AL = Character to display. */
       /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
       /* CX = Times to Write Char */
477
       TRACE("Write Character at Cursor\n");
478 479 480
       write_char_attribute_at_cursor(AL_reg(context), BH_reg(context), 
          0, CX_reg(context));
       break;
Alexandre Julliard's avatar
Alexandre Julliard committed
481 482 483 484

    case 0x0b: 
        switch BH_reg(context) {
        case 0x00: /* SET BACKGROUND/BORDER COLOR */
485 486 487 488 489 490 491 492 493
            /* In text modes, this sets only the border... */
            /* According to the interrupt list and one of my books. */
            /* Funny though that Beyond Zork seems to indicate that it 
               also sets up the default background attributes for clears
               and scrolls... */
            /* Bear in mind here that we do not want to change,
               apparantly, the foreground or attribute of the background
               with this call, so we should check first to see what the
               foreground already is... FIXME */
494
            TRACE("Set Background/Border Color: %d\n", 
495
               BL_reg(context));
496 497
            CONSOLE_SetBackgroundColor(color_palette[0],
               color_palette[BL_reg(context)]);   
Alexandre Julliard's avatar
Alexandre Julliard committed
498 499
            break;
        case 0x01: /* SET PALETTE */
500
            FIXME("Set Palette - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
501 502
            break;
        default:
503
            FIXME("INT 10 AH = 0x0b BH = 0x%x - Unknown\n", 
Alexandre Julliard's avatar
Alexandre Julliard committed
504 505 506 507 508 509 510
               BH_reg(context));
            break;
        }
        break;

    case 0x0c: /* WRITE GRAPHICS PIXEL */
        /* Not in graphics mode, can ignore w/o error */
511
        FIXME("Write Graphics Pixel - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
512 513 514 515
        break;
        
    case 0x0d: /* READ GRAPHICS PIXEL */
        /* Not in graphics mode, can ignore w/o error */
516
        FIXME("Read Graphics Pixel - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
517 518 519
        break;
              
    case 0x0e: /* TELETYPE OUTPUT */
520
        TRACE("Teletype Output\n");
521
        CONSOLE_Write(AL_reg(context), 0, 0, 0);
Alexandre Julliard's avatar
Alexandre Julliard committed
522 523 524
        break;

    case 0x0f: /* GET CURRENT VIDEO MODE */
525
        TRACE("Get current video mode\n");
526
        /* Note: This should not be a constant value. */
527 528
        AL_reg(context) = DOSMEM_BiosData()->VideoMode;
        AH_reg(context) = DOSMEM_BiosData()->VideoColumns;
529
        BH_reg(context) = 0; /* Display page 0 */
Alexandre Julliard's avatar
Alexandre Julliard committed
530 531 532 533 534
        break;

    case 0x10: 
        switch AL_reg(context) {
        case 0x00: /* SET SINGLE PALETTE REGISTER */
535
            FIXME("Set Single Palette Register - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
536 537
            break;
        case 0x01: /* SET BORDER (OVERSCAN) */
538
            /* Text terminals have no overscan */
539
            TRACE("Set Border (Overscan) - Ignored\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
540 541
            break;
        case 0x02: /* SET ALL PALETTE REGISTERS */
542
            FIXME("Set all palette registers - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
543 544
            break;
        case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
545
            FIXME("Toggle Intensity/Blinking Bit - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
546 547
            break;
        case 0x07: /* GET INDIVIDUAL PALETTE REGISTER */
548
            FIXME("Get Individual Palette Register - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
549 550
            break;
        case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
551
            FIXME(
Alexandre Julliard's avatar
Alexandre Julliard committed
552 553 554
               "Read Overscan (Border Color) Register - Not Supported\n");
            break;
        case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
555
            FIXME(
Alexandre Julliard's avatar
Alexandre Julliard committed
556 557 558 559
               "Read All Palette Registers and Overscan Register "
               " - Not Supported\n");
            break;
        case 0x10: /* SET INDIVIDUAL DAC REGISTER */
560
            FIXME("Set Individual DAC register - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
561 562
            break;
        case 0x12: /* SET BLOCK OF DAC REGISTERS */
563
            FIXME("Set Block of DAC registers - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
564 565
            break;
        case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
566
            FIXME("Select video DAC color page - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
567 568
            break;
        case 0x15: /* READ INDIVIDUAL DAC REGISTER */
569
            FIXME("Read individual DAC register - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
570 571
            break;
        case 0x17: /* READ BLOCK OF DAC REGISTERS */
572
            FIXME("Read block of DAC registers - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
573 574
            break;
        case 0x18: /* SET PEL MASK */
575
            FIXME("Set PEL mask - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
576 577
            break;
        case 0x19: /* READ PEL MASK */
578
            FIXME("Read PEL mask - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
579 580
            break;
        case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
581
            FIXME("Get video DAC color page state - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
582 583
            break;
        case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
584
            FIXME("Perform Gray-scale summing - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
585 586
            break;
        default:
587
            FIXME("INT 10 AH = 0x10 AL = 0x%x - Unknown\n", 
Alexandre Julliard's avatar
Alexandre Julliard committed
588 589 590 591 592 593 594 595
               AL_reg(context));
            break;
        }
        break;

    case 0x11: /* TEXT MODE CHARGEN */
        /* Note that second subfunction is *almost* identical. */
        /* See INTERRUPT.A for details. */
Jess Haas's avatar
Jess Haas committed
596
        switch AL_reg(context) {
Alexandre Julliard's avatar
Alexandre Julliard committed
597 598
        case 0x00: /* LOAD USER SPECIFIED PATTERNS */
        case 0x10:
599
            FIXME("Load User Specified Patterns - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
600 601 602
            break;
        case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
        case 0x11:
603
            FIXME("Load ROM Monochrome Patterns - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
604 605 606
            break;
        case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
        case 0x12:
607
            FIXME(
Alexandre Julliard's avatar
Alexandre Julliard committed
608 609 610
                "Load ROM 8x8 Double Dot Patterns - Not Supported\n");       
            break;
        case 0x03: /* SET BLOCK SPECIFIER */
611
            FIXME("Set Block Specifier - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
612 613 614
            break;
        case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
        case 0x14:
615
            FIXME("Load ROM 8x16 Character Set - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
616 617
            break;
        case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
618
            FIXME("Set User 8x16 Graphics Chars - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
619 620
            break;
        case 0x21: /* SET USER GRAPICS CHARACTERS */
621
            FIXME("Set User Graphics Characters - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
622 623
            break;
        case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
624
            FIXME("Set ROM 8x14 Graphics Chars - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
625 626
            break;
        case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
627
            FIXME(
Alexandre Julliard's avatar
Alexandre Julliard committed
628 629 630
                "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
            break;
        case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
631
            FIXME("Load 8x16 Graphic Chars - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
632 633
            break;
        case 0x30: /* GET FONT INFORMATION */
634
            FIXME("Get Font Information - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
635 636
            break;
        default:
637
            FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
Alexandre Julliard's avatar
Alexandre Julliard committed
638 639 640 641 642 643 644 645
               AL_reg(context));
            break;
        }
        break;
        
    case 0x12: /* ALTERNATE FUNCTION SELECT */
        switch BL_reg(context) {
        case 0x10: /* GET EGA INFO */
646
            TRACE("EGA info requested\n");
647
            BH_reg(context) = 0x00;   /* Color screen */
648 649 650 651
            BL_reg(context) =
                DOSMEM_BiosData()->ModeOptions >> 5; /* EGA memory size */
            CX_reg(context) =
                DOSMEM_BiosData()->FeatureBitsSwitches;
Alexandre Julliard's avatar
Alexandre Julliard committed
652 653
            break;
        case 0x20: /* ALTERNATE PRTSC */
654
            FIXME("Install Alternate Print Screen - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
655 656
            break;
        case 0x30: /* SELECT VERTICAL RESOULTION */
657
            FIXME("Select vertical resolution - not supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
658
            break;
659
        case 0x31: /* ENABLE/DISABLE DEFAULT PALETTE LOADING */
660
            FIXME("Default palette loading - not supported\n");
661 662 663
            DOSMEM_BiosData()->VGASettings =
                (DOSMEM_BiosData()->VGASettings & 0xf7) |
                ((AL_reg(context) == 1) << 3);
Alexandre Julliard's avatar
Alexandre Julliard committed
664 665
            break;
        case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
666
            FIXME("Video Addressing - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
667 668
            break;
        case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
669
            FIXME("Gray Scale Summing - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
670 671
            break;
        case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
672
            TRACE("Set cursor emulation to %d\n", AL_reg(context));
673 674
            DOSMEM_BiosData()->ModeOptions =
                (DOSMEM_BiosData()->ModeOptions & 0xfe)|(AL_reg(context) == 1);
Alexandre Julliard's avatar
Alexandre Julliard committed
675 676
            break;
        case 0x36: /* VIDEO ADDRESS CONTROL */
677
            FIXME("Video Address Control - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
678 679
            break;
        default:
680
            FIXME("INT 10 AH = 0x11 AL = 0x%x - Unknown\n", 
Alexandre Julliard's avatar
Alexandre Julliard committed
681 682
               AL_reg(context));
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
683 684
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
685 686 687

    case 0x13: /* WRITE STRING */
        /* This one does not imply that string be at cursor. */
688
        FIXME("Write String - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
689 690 691 692 693
        break;
                             
    case 0x1a: 
        switch AL_reg(context) {
        case 0x00: /* GET DISPLAY COMBINATION CODE */
694
            TRACE("Get Display Combination Code\n");
695 696 697
            AX_reg(context) = 0x001a;
            BL_reg(context) = 0x08; /* VGA w/ color analog display */
            BH_reg(context) = 0x00; /* No secondary hardware */
Alexandre Julliard's avatar
Alexandre Julliard committed
698 699
            break;
        case 0x01: /* SET DISPLAY COMBINATION CODE */
700
            FIXME("Set Display Combination Code - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
701 702
            break;
        default:
703
            FIXME("INT 10 AH = 0x1a AL = 0x%x - Unknown\n", 
Alexandre Julliard's avatar
Alexandre Julliard committed
704 705 706 707 708 709
               AL_reg(context));
            break;
        }
    break;

    case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
710
        FIXME("Get functionality/state information - partially implemented\n");
711 712 713 714 715 716 717 718 719
        if (BX_reg(context) == 0x0)
        {
          AL_reg(context) = 0x1b;
          if (ISV86(context)) /* real */
            ES_reg(context) = 0xf000;
          else
            ES_reg(context) = DOSMEM_BiosSysSeg;
          BX_reg(context) = 0xe000;
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
720 721 722
        break;

    case 0x1c: /* SAVE/RESTORE VIDEO STATE */
723
        FIXME("Save/Restore Video State - Not Supported\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
724
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
725

726 727 728
    case 0x4f: /* Get SuperVGA INFORMATION */
        {
          BYTE *p =
729 730
               CTX_SEG_OFF_TO_LIN(context, ES_reg(context), EDI_reg(context));
          /* BOOL16 vesa20 = (*(DWORD *)p == *(DWORD *)"VBE2"); */
731
  
732
          TRACE("Get SuperVGA information\n");
733
          AH_reg(context) = 0;
734
          *(DWORD *)p = *(DWORD *)"VESA";
735
          *(WORD *)(p+0x04) = 0x0200; /* VESA 2.0 */
736
          *(DWORD *)(p+0x06) = 0x00000000; /* pointer to OEM name */
737 738 739
          *(DWORD *)(p+0x0a) = 0xfffffffd; /* capabilities flags :-) */
        }
        break;
740 741 742 743 744 745
        case 0xef:  /* get video mode for hercules-compatables   */
                    /* There's no reason to really support this  */
                    /* is there?....................(A.C.)       */
                TRACE("Just report the video not hercules compatable\n");
                DX_reg(context) = 0xffff;
                break; 
Alexandre Julliard's avatar
Alexandre Julliard committed
746
    default:
747
        FIXME("Unknown - 0x%x\n", AH_reg(context));
Alexandre Julliard's avatar
Alexandre Julliard committed
748
        INT_BARF( context, 0x10 );
Alexandre Julliard's avatar
Alexandre Julliard committed
749
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
750
}
751
}
752 753 754 755

static void write_char_attribute_at_cursor(char output, char page_num, 
       char attribute, short times)
{
756 757 758 759 760
    /* Contrary to the interrupt list, this routine should not advance
       the cursor. To keep this logic simple, we won't use the
       CONSOLE_Put() routine. 
    */

761 762 763 764 765
    int wattribute, fg_color, bg_color;
    char x, y;

    if (page_num) /* Only support one text page right now */
    {
766
       FIXME("Cannot write to alternate page %d", page_num);
767 768 769
       return;
    }  

770 771 772
    conv_text_mode_attributes(attribute, &fg_color, &bg_color,
        &wattribute);

773
    TRACE("Fore: %d Back: %d\n", fg_color, bg_color);
774

775
    CONSOLE_GetCursorPosition(&x, &y);
776 777 778 779 780 781 782

    while (times)
    {
       CONSOLE_Write(output, fg_color, bg_color, attribute);           
       times--;
    }
  
783
    CONSOLE_MoveCursor(x, y);
784 785
}

786 787
static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
   int *wattribute)
788
{
789 790
    /* This is a local function to convert the text-mode attributes
       to Wine's color and attribute scheme */
791

792
    /* Foreground Color is stored in bits 3 through 0 */
793 794 795
    /* Background Color is stored in bits 6 through 4 */
    /* If this has bit 7 set, then we need to blink */

796 797
    *fg = color_palette[attribute & 15];
    *bg = color_palette[(attribute & 112) / 16];
798 799
    *wattribute = attribute & 128;

800 801 802 803 804
}

static void scroll_window(int direction, char lines, char row1, 
   char col1, char row2, char col2, char attribute)
{
805
   int wattribute, bg_color, fg_color;
806

807 808
   conv_text_mode_attributes(attribute, &fg_color, &bg_color,
      &wattribute);
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825

   if (!lines) /* Actually, clear the window */
   {
      CONSOLE_ClearWindow(row1, col1, row2, col2, bg_color, wattribute);
   }
   else if (direction == SCROLL_UP)
   {
      CONSOLE_ScrollUpWindow(row1, col1, row2, col2, lines, bg_color,
         wattribute);
   }
   else
   {
      CONSOLE_ScrollDownWindow(row1, col1, row2, col2, lines, bg_color,
         wattribute);
   }
}