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