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