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