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