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