Initialized return value of 16->32 conversion of WM_MDIGETACTIVE in
[wine/dcerpc.git] / msdos / int10.c
blobd879d477040f5d713e3f0943b8be896c80cf2be5
1 /*
2 * BIOS interrupt 10h handler
3 */
5 #include <stdlib.h>
6 #include "miscemu.h"
7 #include "vga.h"
8 /* #define DEBUG_INT */
9 #include "debug.h"
10 #include "console.h"
12 static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
13 int *wattribute);
14 static void write_char_attribute_at_cursor(char output, char page_num,
15 char attribute, short times);
16 static void scroll_window(int direction, char lines, char row1,
17 char col1, char row2, char col2, char attribute);
19 static int color_pallet[16];
21 #define SCROLL_UP 1
22 #define SCROLL_DOWN 2
24 /**********************************************************************
25 * INT_Int10Handler
27 * Handler for int 10h (video).
29 * NOTE:
30 * Most INT 10 functions for text-mode, CGA, EGA, and VGA cards
31 * are present in this list. (SVGA and XGA are not) That is not
32 * to say that all these functions should be supported, but if
33 * anyone is braindamaged enough to want to emulate one of these
34 * beasts then this should get you started.
36 * NOTE:
37 * Several common graphical extensions used by Microsoft hook
38 * off of here. I have *not* added them to this list (yet). They
39 * include:
41 * MSHERC.COM - More functionality for Hercules cards.
42 * EGA.SYS (also MOUSE.COM) - More for EGA cards.
44 * Yes, MS also added this support into their mouse driver. Don't
45 * ask me, I don't work for them.
47 * Joseph Pranevich - 9/98
50 void WINAPI INT_Int10Handler( CONTEXT *context )
52 static int registered_colors = FALSE;
53 static int video_mode = 7;
54 static int video_columns = 80;
56 if (!registered_colors)
58 /* Colors:
59 0000b black 1000b dark gray
60 0001b blue 1001b light blue
61 0010b green 1010b light green
62 0011b cyan 1011b light cyan
63 0100b red 1100b light red
64 0101b magenta 1101b light magenta
65 0110b brown 1110b yellow
66 0111b light gray 1111b white
69 /* These AllocColor calls have the side-effect of triggering
70 ternimal initialization as xx_Init() is no longer called on
71 startup. Which is what we want anyway. */
73 color_pallet[0] = CONSOLE_AllocColor(WINE_BLACK);
74 color_pallet[1] = CONSOLE_AllocColor(WINE_BLUE);
75 color_pallet[2] = CONSOLE_AllocColor(WINE_GREEN);
76 color_pallet[3] = CONSOLE_AllocColor(WINE_CYAN);
77 color_pallet[4] = CONSOLE_AllocColor(WINE_RED);
78 color_pallet[5] = CONSOLE_AllocColor(WINE_MAGENTA);
79 color_pallet[6] = CONSOLE_AllocColor(WINE_BROWN);
80 color_pallet[7] = CONSOLE_AllocColor(WINE_LIGHT_GRAY);
81 color_pallet[8] = CONSOLE_AllocColor(WINE_DARK_GRAY);
82 color_pallet[9] = CONSOLE_AllocColor(WINE_LIGHT_BLUE);
83 color_pallet[10] = CONSOLE_AllocColor(WINE_LIGHT_GREEN);
84 color_pallet[11] = CONSOLE_AllocColor(WINE_LIGHT_CYAN);
85 color_pallet[12] = CONSOLE_AllocColor(WINE_LIGHT_RED);
86 color_pallet[13] = CONSOLE_AllocColor(WINE_LIGHT_MAGENTA);
87 color_pallet[14] = CONSOLE_AllocColor(WINE_YELLOW);
88 color_pallet[15] = CONSOLE_AllocColor(WINE_WHITE);
91 switch(AH_reg(context)) {
93 case 0x00: /* SET VIDEO MODE */
94 /* Text Modes: */
95 /* (mode) (text rows/cols)
96 0x00 - 40x25
97 0x01 - 40x25
98 0x02 - 80x25
99 0x03 - 80x25 or 80x43 or 80x50 (assume 80x25)
100 0x07 - 80x25
103 switch (AL_reg(context)) {
104 case 0x00: /* 40x25 */
105 case 0x01:
106 VGA_Exit();
107 TRACE(int10, "Set Video Mode - Set to Text - 0x0%x\n",
108 AL_reg(context));
109 CONSOLE_ResizeScreen(40, 25);
110 CONSOLE_ClearScreen();
111 video_mode = AL_reg(context);
112 video_columns = 40;
113 break;
114 case 0x02:
115 case 0x03:
116 case 0x07:
117 VGA_Exit();
118 TRACE(int10, "Set Video Mode - Set to Text - 0x0%x\n",
119 AL_reg(context));
120 CONSOLE_ResizeScreen(80, 25);
121 CONSOLE_ClearScreen();
122 video_mode = AL_reg(context);
123 video_columns = 80;
124 break;
125 case 0x13:
126 TRACE(int10, "Setting VGA 320x200 256-color mode\n");
127 VGA_SetMode(320,200,8);
128 video_mode = AL_reg(context);
129 break;
130 default:
131 FIXME(int10, "Set Video Mode (0x%x) - Not Supported\n",
132 AL_reg(context));
134 break;
136 case 0x01: /* SET CURSOR SHAPE */
137 FIXME(int10, "Set Cursor Shape - Not Supported\n");
138 break;
140 case 0x02: /* SET CURSOR POSITION */
141 /* BH = Page Number */ /* Not supported */
142 /* DH = Row */ /* 0 is left */
143 /* DL = Column */ /* 0 is top */
144 if (BH_reg(context))
146 FIXME(int10, "Set Cursor Position: Cannot set to page %d\n",
147 BH_reg(context));
149 else
151 CONSOLE_MoveCursor(DH_reg(context), DL_reg(context));
152 TRACE(int10, "Set Cursor Position: %d %d\n", DH_reg(context),
153 DL_reg(context));
155 break;
157 case 0x03: /* GET CURSOR POSITION AND SIZE */
158 FIXME(int10, "Get Cursor Position and Size - Not Supported\n");
159 CX_reg(context) = 0x0000; /* Bogus cursor data */
160 DX_reg(context) = 0x0000;
161 break;
163 case 0x04: /* READ LIGHT PEN POSITION */
164 FIXME(int10, "Read Light Pen Position - Not Supported\n");
165 AH_reg(context) = 0x00; /* Not down */
166 break;
168 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
169 FIXME(int10, "Select Active Display Page - Not Supported\n");
170 break;
172 case 0x06: /* SCROLL UP WINDOW */
173 /* AL = Lines to scroll */
174 /* BH = Attribute */
175 /* CH,CL = row, col upper-left */
176 /* DH,DL = row, col lower-right */
177 scroll_window(SCROLL_UP, AL_reg(context), CH_reg(context),
178 CL_reg(context), DH_reg(context), DL_reg(context),
179 BH_reg(context));
180 TRACE(int10, "Scroll Up Window %d\n", AL_reg(context));
181 break;
183 case 0x07: /* SCROLL DOWN WINDOW */
184 /* AL = Lines to scroll */
185 /* BH = Attribute */
186 /* CH,CL = row, col upper-left */
187 /* DH,DL = row, col lower-right */
188 scroll_window(SCROLL_DOWN, AL_reg(context), CH_reg(context),
189 CL_reg(context), DH_reg(context), DL_reg(context),
190 BH_reg(context));
191 TRACE(int10, "Scroll Down Window %d\n", AL_reg(context));
192 break;
194 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
196 /* Note here that color data returned is bogus, will fix later. */
197 char ch;
198 int bg, fg, attr;
199 if (BH_reg(context)) /* Write to different page */
201 FIXME(int10, "Read Character and Attribute at Cursor Position -"
202 " Can't read from non-0 page\n");
203 AL_reg(context) = ' '; /* That page is blank */
204 AH_reg(context) = 7;
206 else
208 TRACE(int10,
209 "Read Character and Attribute at Cursor Position\n");
210 CONSOLE_GetCharacterAtCursor(&ch, &fg, &bg, &attr);
211 AL_reg(context) = ch;
212 AH_reg(context) = 7; /* FIXME: We're assuming wh on bl */
215 break;
217 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
218 /* AL = Character to display. */
219 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
220 /* BL = Attribute / Color */
221 /* CX = Times to Write Char */
222 /* Note here that the cursor is not advanced. */
223 write_char_attribute_at_cursor(AL_reg(context), BH_reg(context),
224 BL_reg(context), CX_reg(context));
225 if (CX_reg(context) > 1)
226 TRACE(int10, "Write Character and Attribute at Cursor Position "
227 "(Rep. %d) %c\n", CX_reg(context), AL_reg(context));
228 else
229 TRACE(int10, "Write Character and Attribute at Cursor"
230 "Position: %c\n", AL_reg(context));
231 break;
233 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
234 /* AL = Character to display. */
235 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
236 /* CX = Times to Write Char */
237 TRACE(int10, "Write Character at Cursor\n");
238 write_char_attribute_at_cursor(AL_reg(context), BH_reg(context),
239 0, CX_reg(context));
240 break;
242 case 0x0b:
243 switch BH_reg(context) {
244 case 0x00: /* SET BACKGROUND/BORDER COLOR */
245 /* In text modes, this sets only the border */
246 TRACE(int10, "Set Background/Border Color - Ignored\n");
247 break;
248 case 0x01: /* SET PALETTE */
249 FIXME(int10, "Set Palette - Not Supported\n");
250 break;
251 default:
252 FIXME(int10, "INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
253 BH_reg(context));
254 break;
256 break;
258 case 0x0c: /* WRITE GRAPHICS PIXEL */
259 /* Not in graphics mode, can ignore w/o error */
260 FIXME(int10, "Write Graphics Pixel - Not Supported\n");
261 break;
263 case 0x0d: /* READ GRAPHICS PIXEL */
264 /* Not in graphics mode, can ignore w/o error */
265 FIXME(int10, "Read Graphics Pixel - Not Supported\n");
266 break;
268 case 0x0e: /* TELETYPE OUTPUT */
269 TRACE(int10, "Teletype Output\n");
270 CONSOLE_Write(AL_reg(context), 0, 0, 0);
271 break;
273 case 0x0f: /* GET CURRENT VIDEO MODE */
274 TRACE(int10, "Get Current Video Mode\n");
275 /* Note: This should not be a constant value. */
276 AL_reg(context) = video_mode;
277 AH_reg(context) = video_columns;
278 BH_reg(context) = 0; /* Display page 0 */
279 break;
281 case 0x10:
282 switch AL_reg(context) {
283 case 0x00: /* SET SINGLE PALETTE REGISTER */
284 FIXME(int10, "Set Single Palette Register - Not Supported\n");
285 break;
286 case 0x01: /* SET BORDER (OVERSCAN) */
287 /* Text terminals have no overscan */
288 TRACE(int10, "Set Border (Overscan) - Ignored\n");
289 break;
290 case 0x02: /* SET ALL PALETTE REGISTERS */
291 FIXME(int10, "Set all palette registers - Not Supported\n");
292 break;
293 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
294 FIXME(int10, "Toggle Intensity/Blinking Bit - Not Supported\n");
295 break;
296 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER */
297 FIXME(int10, "Get Individual Palette Register - Not Supported\n");
298 break;
299 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
300 FIXME(int10,
301 "Read Overscan (Border Color) Register - Not Supported\n");
302 break;
303 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
304 FIXME(int10,
305 "Read All Palette Registers and Overscan Register "
306 " - Not Supported\n");
307 break;
308 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
309 FIXME(int10, "Set Individual DAC register - Not Supported\n");
310 break;
311 case 0x12: /* SET BLOCK OF DAC REGISTERS */
312 FIXME(int10, "Set Block of DAC registers - Not Supported\n");
313 break;
314 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
315 FIXME(int10, "Select video DAC color page - Not Supported\n");
316 break;
317 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
318 FIXME(int10, "Read individual DAC register - Not Supported\n");
319 break;
320 case 0x17: /* READ BLOCK OF DAC REGISTERS */
321 FIXME(int10, "Read block of DAC registers - Not Supported\n");
322 break;
323 case 0x18: /* SET PEL MASK */
324 FIXME(int10, "Set PEL mask - Not Supported\n");
325 break;
326 case 0x19: /* READ PEL MASK */
327 FIXME(int10, "Read PEL mask - Not Supported\n");
328 break;
329 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
330 FIXME(int10, "Get video DAC color page state - Not Supported\n");
331 break;
332 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
333 FIXME(int10, "Perform Gray-scale summing - Not Supported\n");
334 break;
335 default:
336 FIXME(int10, "INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
337 AL_reg(context));
338 break;
340 break;
342 case 0x11: /* TEXT MODE CHARGEN */
343 /* Note that second subfunction is *almost* identical. */
344 /* See INTERRUPT.A for details. */
345 switch AH_reg(context) {
346 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
347 case 0x10:
348 FIXME(int10, "Load User Specified Patterns - Not Supported\n");
349 break;
350 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
351 case 0x11:
352 FIXME(int10, "Load ROM Monochrome Patterns - Not Supported\n");
353 break;
354 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
355 case 0x12:
356 FIXME(int10,
357 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
358 break;
359 case 0x03: /* SET BLOCK SPECIFIER */
360 FIXME(int10, "Set Block Specifier - Not Supported\n");
361 break;
362 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
363 case 0x14:
364 FIXME(int10, "Load ROM 8x16 Character Set - Not Supported\n");
365 break;
366 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
367 FIXME(int10, "Set User 8x16 Graphics Chars - Not Supported\n");
368 break;
369 case 0x21: /* SET USER GRAPICS CHARACTERS */
370 FIXME(int10, "Set User Graphics Characters - Not Supported\n");
371 break;
372 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
373 FIXME(int10, "Set ROM 8x14 Graphics Chars - Not Supported\n");
374 break;
375 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
376 FIXME(int10,
377 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
378 break;
379 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
380 FIXME(int10, "Load 8x16 Graphic Chars - Not Supported\n");
381 break;
382 case 0x30: /* GET FONT INFORMATION */
383 FIXME(int10, "Get Font Information - Not Supported\n");
384 break;
385 default:
386 FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
387 AL_reg(context));
388 break;
390 break;
392 case 0x12: /* ALTERNATE FUNCTION SELECT */
393 switch BL_reg(context) {
394 case 0x10: /* GET EGA INFO */
395 TRACE(int10, "EGA Info Requested\n");
396 BH_reg(context) = 0x00; /* Color screen */
397 BL_reg(context) = 0x03; /* 256K EGA card */
398 CH_reg(context) = 0x00; /* Switch settings?? */
399 CL_reg(context) = 0x09; /* EGA+ card */
400 break;
401 case 0x20: /* ALTERNATE PRTSC */
402 FIXME(int10, "Install Alternate Print Screen - Not Supported\n");
403 break;
404 case 0x30: /* SELECT VERTICAL RESOULTION */
405 FIXME(int10, "Select Vertical Resoultion - Not Supported\n");
406 break;
407 case 0x31: /* ENABLE/DISABLE PALETTE LOADING */
408 FIXME(int10, "Palette Loading - Not Supported\n");
409 break;
410 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
411 FIXME(int10, "Video Addressing - Not Supported\n");
412 break;
413 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
414 FIXME(int10, "Gray Scale Summing - Not Supported\n");
415 break;
416 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
417 FIXME(int10, "Cursor Emulation - Not Supported\n");
418 break;
419 case 0x36: /* VIDEO ADDRESS CONTROL */
420 FIXME(int10, "Video Address Control - Not Supported\n");
421 break;
422 default:
423 FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
424 AL_reg(context));
425 break;
427 break;
429 case 0x13: /* WRITE STRING */
430 /* This one does not imply that string be at cursor. */
431 FIXME(int10, "Write String - Not Supported\n");
432 break;
434 case 0x1a:
435 switch AL_reg(context) {
436 case 0x00: /* GET DISPLAY COMBINATION CODE */
437 TRACE(int10, "Get Display Combination Code\n");
438 AL_reg(context) = 0x1a;
439 BH_reg(context) = 0x08; /* VGA w/ color analog display */
440 BL_reg(context) = 0x00; /* No secondary hardware */
441 break;
442 case 0x01: /* SET DISPLAY COMBINATION CODE */
443 FIXME(int10, "Set Display Combination Code - Not Supported\n");
444 break;
445 default:
446 FIXME(int10, "INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
447 AL_reg(context));
448 break;
450 break;
452 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
453 FIXME(int10, "Get Functionality/State Information - Not Supported\n");
454 break;
456 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
457 FIXME(int10, "Save/Restore Video State - Not Supported\n");
458 break;
460 default:
461 FIXME(int10, "Unknown - 0x%x\n", AH_reg(context));
462 INT_BARF( context, 0x10 );
466 static void write_char_attribute_at_cursor(char output, char page_num,
467 char attribute, short times)
469 /* Contrary to the interrupt list, this routine should not advance
470 the cursor. To keep this logic simple, we won't use the
471 CONSOLE_Put() routine.
474 int wattribute, fg_color, bg_color;
475 char x, y;
477 if (page_num) /* Only support one text page right now */
479 FIXME(int10, "Cannot write to alternate page %d", page_num);
480 return;
483 conv_text_mode_attributes(attribute, &fg_color, &bg_color,
484 &wattribute);
486 TRACE(int10, "Fore: %d Back: %d\n", fg_color, bg_color);
488 CONSOLE_GetCursorPosition(&x, &y);
490 while (times)
492 CONSOLE_Write(output, fg_color, bg_color, attribute);
493 times--;
496 CONSOLE_MoveCursor(x, y);
499 static void conv_text_mode_attributes(char attribute, int *fg, int *bg,
500 int *wattribute)
502 /* This is a local function to convert the text-mode attributes
503 to Wine's color and attribute scheme */
505 /* Foreground Color is stored in bits 3 through 0 */
506 /* Background Color is stored in bits 6 through 4 */
507 /* If this has bit 7 set, then we need to blink */
509 *fg = color_pallet[attribute & 15];
510 *bg = color_pallet[(attribute & 112) / 16];
511 *wattribute = attribute & 128;
515 static void scroll_window(int direction, char lines, char row1,
516 char col1, char row2, char col2, char attribute)
518 int wattribute, bg_color, fg_color;
520 conv_text_mode_attributes(attribute, &fg_color, &bg_color,
521 &wattribute);
523 if (!lines) /* Actually, clear the window */
525 CONSOLE_ClearWindow(row1, col1, row2, col2, bg_color, wattribute);
527 else if (direction == SCROLL_UP)
529 CONSOLE_ScrollUpWindow(row1, col1, row2, col2, lines, bg_color,
530 wattribute);
532 else
534 CONSOLE_ScrollDownWindow(row1, col1, row2, col2, lines, bg_color,
535 wattribute);