Hook into the (stubbed) resize code in msdos int10.
[wine/multimedia.git] / msdos / int10.c
blob9a870af7dd6a7981306cf9c8b7f93d48156e9ab5
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 int conv_text_mode_attribute_attribute(char attribute);
13 static int conv_text_mode_attribute_fg_color(char attribute);
14 static int conv_text_mode_attribute_bg_color(char attribute);
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 #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
49 void WINAPI INT_Int10Handler( CONTEXT *context )
51 switch(AH_reg(context)) {
53 case 0x00: /* SET VIDEO MODE */
54 /* Text Modes: (can xterm or similar change text rows/cols?) */
55 /* Answer: Yes. We can add that later. */
56 /* Er, maybe. I thought resizeterm() did it, I was wrong. */
57 /* (mode) (text rows/cols)
58 0x00 - 40x25
59 0x01 - 40x25
60 0x02 - 80x25
61 0x03 - 80x25 or 80x43 or 80x50
62 0x07 - 80x25
65 /* We may or may not want to do a refresh between the resize and
66 the clear... */
68 switch (AL_reg(context)) {
69 case 0x00: /* 40x25 */
70 case 0x01:
71 VGA_Exit();
72 TRACE(int10, "Set Video Mode - Set to Text - 0x0%x\n",
73 AL_reg(context));
74 CONSOLE_ResizeScreen(40, 25);
75 CONSOLE_ClearScreen();
76 break;
77 case 0x02:
78 case 0x03:
79 case 0x07:
80 VGA_Exit();
81 TRACE(int10, "Set Video Mode - Set to Text - 0x0%x\n",
82 AL_reg(context));
83 CONSOLE_ResizeScreen(80, 25);
84 CONSOLE_ClearScreen();
85 break;
86 case 0x13:
87 TRACE(int10, "Setting VGA 320x200 256-color mode\n");
88 VGA_SetMode(320,200,8);
89 break;
90 default:
91 FIXME(int10, "Set Video Mode (0x%x) - Not Supported\n",
92 AL_reg(context));
94 break;
96 case 0x01: /* SET CURSOR SHAPE */
97 FIXME(int10, "Set Cursor Shape - Not Supported\n");
98 break;
100 case 0x02: /* SET CURSOR POSITION */
101 /* BH = Page Number */ /* Not supported */
102 /* DH = Row */ /* 0 is left */
103 /* DL = Column */ /* 0 is top */
104 if (BH_reg(context))
106 FIXME(int10, "Set Cursor Position: Cannot set to page %d\n",
107 BH_reg(context));
109 else
111 CONSOLE_MoveCursor(DH_reg(context), DL_reg(context));
112 TRACE(int10, "Set Cursor Position: %d %d\n", DH_reg(context),
113 DL_reg(context));
115 break;
117 case 0x03: /* GET CURSOR POSITION AND SIZE */
118 FIXME(int10, "Get Cursor Position and Size - Not Supported\n");
119 CX_reg(context) = 0x0000; /* Bogus cursor data */
120 DX_reg(context) = 0x0000;
121 break;
123 case 0x04: /* READ LIGHT PEN POSITION */
124 FIXME(int10, "Read Light Pen Position - Not Supported\n");
125 AH_reg(context) = 0x00; /* Not down */
126 break;
128 case 0x05: /* SELECT ACTIVE DISPLAY PAGE */
129 FIXME(int10, "Select Active Display Page - Not Supported\n");
130 break;
132 case 0x06: /* SCROLL UP WINDOW */
133 /* AL = Lines to scroll */
134 /* BH = Attribute */
135 /* CH,CL = row, col upper-left */
136 /* DH,DL = row, col lower-right */
137 scroll_window(SCROLL_UP, AL_reg(context), CH_reg(context),
138 CL_reg(context), DH_reg(context), DL_reg(context),
139 BH_reg(context));
140 TRACE(int10, "Scroll Up Window %d\n", AL_reg(context));
141 break;
143 case 0x07: /* SCROLL DOWN WINDOW */
144 /* AL = Lines to scroll */
145 /* BH = Attribute */
146 /* CH,CL = row, col upper-left */
147 /* DH,DL = row, col lower-right */
148 scroll_window(SCROLL_DOWN, AL_reg(context), CH_reg(context),
149 CL_reg(context), DH_reg(context), DL_reg(context),
150 BH_reg(context));
151 TRACE(int10, "Scroll Down Window %d\n", AL_reg(context));
152 break;
154 case 0x08: /* READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
155 FIXME(int10,
156 "Read Character and Attribute at Cursor Position - Not Supported\n");
157 break;
159 case 0x09: /* WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION */
160 /* AL = Character to display. */
161 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
162 /* BL = Attribute / Color */
163 /* CX = Times to Write Char */
164 /* !NOTE!: It appears as if the cursor is not advanced if CX > 1 */
165 write_char_attribute_at_cursor(AL_reg(context), BH_reg(context),
166 BL_reg(context), CX_reg(context));
167 if (CX_reg(context) > 1)
168 TRACE(int10, "Write Character and Attribute at Cursor Position "
169 "(Rep. %d) %c\n", CX_reg(context), AL_reg(context));
170 else
171 TRACE(int10, "Write Character and Attribute at Cursor"
172 "Position: %c\n", AL_reg(context));
173 break;
175 case 0x0a: /* WRITE CHARACTER ONLY AT CURSOR POSITION */
176 /* AL = Character to display. */
177 /* BH = Page Number */ /* We can't write to non-0 pages, yet. */
178 /* CX = Times to Write Char */
179 TRACE(int10, "Write Character at Cursor\n");
180 write_char_attribute_at_cursor(AL_reg(context), BH_reg(context),
181 0, CX_reg(context));
182 break;
184 case 0x0b:
185 switch BH_reg(context) {
186 case 0x00: /* SET BACKGROUND/BORDER COLOR */
187 FIXME(int10, "Set Background/Border Color - Not Supported\n");
188 break;
189 case 0x01: /* SET PALETTE */
190 FIXME(int10, "Set Palette - Not Supported\n");
191 break;
192 default:
193 FIXME(int10, "INT 10 AH = 0x0b BH = 0x%x - Unknown\n",
194 BH_reg(context));
195 break;
197 break;
199 case 0x0c: /* WRITE GRAPHICS PIXEL */
200 /* Not in graphics mode, can ignore w/o error */
201 FIXME(int10, "Write Graphics Pixel - Not Supported\n");
202 break;
204 case 0x0d: /* READ GRAPHICS PIXEL */
205 /* Not in graphics mode, can ignore w/o error */
206 FIXME(int10, "Read Graphics Pixel - Not Supported\n");
207 break;
209 case 0x0e: /* TELETYPE OUTPUT */
210 TRACE(int10, "Teletype Output\n");
211 CONSOLE_Write(AL_reg(context), 0, 0, 0);
212 break;
214 case 0x0f: /* GET CURRENT VIDEO MODE */
215 TRACE(int10, "Get Current Video Mode (0x0%x)\n", AL_reg(context));
216 /* Note: This should not be a constant value. */
217 AL_reg(context) = 0x07; /* 80x25 text mode */
218 AH_reg(context) = 80; /* 80 columns */
219 BH_reg(context) = 0; /* Display page 0 */
220 break;
222 case 0x10:
223 switch AL_reg(context) {
224 case 0x00: /* SET SINGLE PALETTE REGISTER */
225 FIXME(int10, "Set Single Palette Register - Not Supported\n");
226 break;
227 case 0x01: /* SET BORDER (OVERSCAN) */
228 /* Text terminals have no overscan */
229 TRACE(int10, "Set Border (Overscan) - Ignored\n");
230 break;
231 case 0x02: /* SET ALL PALETTE REGISTERS */
232 FIXME(int10, "Set all palette registers - Not Supported\n");
233 break;
234 case 0x03: /* TOGGLE INTENSITY/BLINKING BIT */
235 FIXME(int10, "Toggle Intensity/Blinking Bit - Not Supported\n");
236 break;
237 case 0x07: /* GET INDIVIDUAL PALETTE REGISTER */
238 FIXME(int10, "Get Individual Palette Register - Not Supported\n");
239 break;
240 case 0x08: /* READ OVERSCAN (BORDER COLOR) REGISTER */
241 FIXME(int10,
242 "Read Overscan (Border Color) Register - Not Supported\n");
243 break;
244 case 0x09: /* READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER */
245 FIXME(int10,
246 "Read All Palette Registers and Overscan Register "
247 " - Not Supported\n");
248 break;
249 case 0x10: /* SET INDIVIDUAL DAC REGISTER */
250 FIXME(int10, "Set Individual DAC register - Not Supported\n");
251 break;
252 case 0x12: /* SET BLOCK OF DAC REGISTERS */
253 FIXME(int10, "Set Block of DAC registers - Not Supported\n");
254 break;
255 case 0x13: /* SELECT VIDEO DAC COLOR PAGE */
256 FIXME(int10, "Select video DAC color page - Not Supported\n");
257 break;
258 case 0x15: /* READ INDIVIDUAL DAC REGISTER */
259 FIXME(int10, "Read individual DAC register - Not Supported\n");
260 break;
261 case 0x17: /* READ BLOCK OF DAC REGISTERS */
262 FIXME(int10, "Read block of DAC registers - Not Supported\n");
263 break;
264 case 0x18: /* SET PEL MASK */
265 FIXME(int10, "Set PEL mask - Not Supported\n");
266 break;
267 case 0x19: /* READ PEL MASK */
268 FIXME(int10, "Read PEL mask - Not Supported\n");
269 break;
270 case 0x1a: /* GET VIDEO DAC COLOR PAGE STATE */
271 FIXME(int10, "Get video DAC color page state - Not Supported\n");
272 break;
273 case 0x1b: /* PERFORM GRAY-SCALE SUMMING */
274 FIXME(int10, "Perform Gray-scale summing - Not Supported\n");
275 break;
276 default:
277 FIXME(int10, "INT 10 AH = 0x10 AL = 0x%x - Unknown\n",
278 AL_reg(context));
279 break;
281 break;
283 case 0x11: /* TEXT MODE CHARGEN */
284 /* Note that second subfunction is *almost* identical. */
285 /* See INTERRUPT.A for details. */
286 switch AH_reg(context) {
287 case 0x00: /* LOAD USER SPECIFIED PATTERNS */
288 case 0x10:
289 FIXME(int10, "Load User Specified Patterns - Not Supported\n");
290 break;
291 case 0x01: /* LOAD ROM MONOCHROME PATTERNS */
292 case 0x11:
293 FIXME(int10, "Load ROM Monochrome Patterns - Not Supported\n");
294 break;
295 case 0x02: /* LOAD ROM 8x8 DOUBLE-DOT PATTERNS */
296 case 0x12:
297 FIXME(int10,
298 "Load ROM 8x8 Double Dot Patterns - Not Supported\n");
299 break;
300 case 0x03: /* SET BLOCK SPECIFIER */
301 FIXME(int10, "Set Block Specifier - Not Supported\n");
302 break;
303 case 0x04: /* LOAD ROM 8x16 CHARACTER SET */
304 case 0x14:
305 FIXME(int10, "Load ROM 8x16 Character Set - Not Supported\n");
306 break;
307 case 0x20: /* SET USER 8x16 GRAPHICS CHARS */
308 FIXME(int10, "Set User 8x16 Graphics Chars - Not Supported\n");
309 break;
310 case 0x21: /* SET USER GRAPICS CHARACTERS */
311 FIXME(int10, "Set User Graphics Characters - Not Supported\n");
312 break;
313 case 0x22: /* SET ROM 8x14 GRAPHICS CHARS */
314 FIXME(int10, "Set ROM 8x14 Graphics Chars - Not Supported\n");
315 break;
316 case 0x23: /* SET ROM 8x8 DBL DOT CHARS */
317 FIXME(int10,
318 "Set ROM 8x8 Dbl Dot Chars (Graphics) - Not Supported\n");
319 break;
320 case 0x24: /* LOAD 8x16 GRAPHIC CHARS */
321 FIXME(int10, "Load 8x16 Graphic Chars - Not Supported\n");
322 break;
323 case 0x30: /* GET FONT INFORMATION */
324 FIXME(int10, "Get Font Information - Not Supported\n");
325 break;
326 default:
327 FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
328 AL_reg(context));
329 break;
331 break;
333 case 0x12: /* ALTERNATE FUNCTION SELECT */
334 switch BL_reg(context) {
335 case 0x10: /* GET EGA INFO */
336 TRACE(int10, "EGA Info Requested\n");
337 BX_reg(context) = 0x0003;
338 CX_reg(context) = 0x0009;
339 break;
340 case 0x20: /* ALTERNATE PRTSC */
341 FIXME(int10, "Install Alternate Print Screen - Not Supported\n");
342 break;
343 case 0x30: /* SELECT VERTICAL RESOULTION */
344 FIXME(int10, "Select Vertical Resoultion - Not Supported\n");
345 break;
346 case 0x31: /* ENABLE/DISABLE PALETTE LOADING */
347 FIXME(int10, "Palette Loading - Not Supported\n");
348 break;
349 case 0x32: /* ENABLE/DISABLE VIDEO ADDRERSSING */
350 FIXME(int10, "Video Addressing - Not Supported\n");
351 break;
352 case 0x33: /* ENABLE/DISABLE GRAY SCALE SUMMING */
353 FIXME(int10, "Gray Scale Summing - Not Supported\n");
354 break;
355 case 0x34: /* ENABLE/DISABLE CURSOR EMULATION */
356 FIXME(int10, "Cursor Emulation - Not Supported\n");
357 break;
358 case 0x36: /* VIDEO ADDRESS CONTROL */
359 FIXME(int10, "Video Address Control - Not Supported\n");
360 break;
361 default:
362 FIXME(int10, "INT 10 AH = 0x11 AL = 0x%x - Unknown\n",
363 AL_reg(context));
364 break;
366 break;
368 case 0x13: /* WRITE STRING */
369 /* This one does not imply that string be at cursor. */
370 FIXME(int10, "Write String - Not Supported\n");
371 break;
373 case 0x1a:
374 switch AL_reg(context) {
375 case 0x00: /* GET DISPLAY COMBINATION CODE */
376 TRACE(int10, "Get Display Combination Code\n");
377 /* Why are we saying this? */
378 /* Do we need to check if we are in a windows or text app? */
379 BX_reg(context) = 0x0008; /* VGA w/ color analog display */
380 break;
381 case 0x01: /* SET DISPLAY COMBINATION CODE */
382 FIXME(int10, "Set Display Combination Code - Not Supported\n");
383 break;
384 default:
385 FIXME(int10, "INT 10 AH = 0x1a AL = 0x%x - Unknown\n",
386 AL_reg(context));
387 break;
389 break;
391 case 0x1b: /* FUNCTIONALITY/STATE INFORMATION */
392 FIXME(int10, "Get Functionality/State Information - Not Supported\n");
393 break;
395 case 0x1c: /* SAVE/RESTORE VIDEO STATE */
396 FIXME(int10, "Save/Restore Video State - Not Supported\n");
397 break;
399 default:
400 FIXME(int10, "Unknown - 0x%x\n", AH_reg(context));
401 INT_BARF( context, 0x10 );
405 static void write_char_attribute_at_cursor(char output, char page_num,
406 char attribute, short times)
408 /* !NOTE!: */
409 /* It appears that the cursor should not be advanced if times > 1 */
410 /* I will triple check this later but bzork.exe definately points this */
411 /* way */
412 int wattribute, fg_color, bg_color;
413 char x, y;
414 int must_reset = 0;
416 if (page_num) /* Only support one text page right now */
418 FIXME(int10, "Cannot write to alternate page %d", page_num);
419 return;
422 wattribute = conv_text_mode_attribute_attribute(attribute);
423 fg_color = conv_text_mode_attribute_fg_color(attribute);
424 bg_color = conv_text_mode_attribute_bg_color(attribute);
426 if (times > 1)
428 must_reset = 1;
429 CONSOLE_GetCursorPosition(&x, &y);
432 while (times)
434 CONSOLE_Write(output, fg_color, bg_color, attribute);
435 times--;
438 if (must_reset)
439 CONSOLE_MoveCursor(x, y);
442 static int conv_text_mode_attribute_fg_color(char attribute)
444 /* This is a local function to convert the color values
445 in text-mode attributes to Wine's scheme */
447 /* Foreground Color is stored in bits 3 through 0 */
449 /* Colors:
450 0000b black 1000b dark gray
451 0001b blue 1001b light blue
452 0010b green 1010b light green
453 0011b cyan 1011b light cyan
454 0100b red 1100b light red
455 0101b magenta 1101b light magenta
456 0110b brown 1110b yellow
457 0111b light gray 1111b white
460 /* FIXME - We need color values for those and some generic constants */
462 return 0; /* Bogus, temporary data. */
465 static int conv_text_mode_attribute_bg_color(char attribute)
467 /* This is a local function to convert the color values
468 in text-mode attributes to Wine's scheme */
470 /* Background Color is stored in bits 6 through 4 */
472 /* Colors same as above, but only the left column */
474 /* FIXME - We need color values for those and some generic constants */
476 return 0; /* Bogus, temporary data. */
479 static int conv_text_mode_attribute_attribute(char attribute)
481 /* This is a local function to convert the attribute values
482 in text-mode attributes to Wine's scheme */
484 /* If this has bit 7 set, then we need to blink */
486 if (255 && attribute)
488 /* return TEXT_ATTRIBUTE_BLINK; */
491 return 0; /* Bogus data */
494 static void scroll_window(int direction, char lines, char row1,
495 char col1, char row2, char col2, char attribute)
497 int wattribute, bg_color;
499 wattribute = conv_text_mode_attribute_attribute(attribute);
500 bg_color = conv_text_mode_attribute_bg_color(attribute);
502 if (!lines) /* Actually, clear the window */
504 CONSOLE_ClearWindow(row1, col1, row2, col2, bg_color, wattribute);
506 else if (direction == SCROLL_UP)
508 CONSOLE_ScrollUpWindow(row1, col1, row2, col2, lines, bg_color,
509 wattribute);
511 else
513 CONSOLE_ScrollDownWindow(row1, col1, row2, col2, lines, bg_color,
514 wattribute);