libpayload/configs: Add default configuration with TinyCurses enabled
[coreboot.git] / util / vgabios / int10.c
blobbccb3d9954bc66ab07fed6ca7cf8402edc58dff2
1 #include <stdio.h>
2 #include "test.h"
3 #include "pci.h"
5 void x86emu_dump_xregs(void);
6 extern ptr current;
7 extern int verbose;
10 #ifndef _PC
12 * This is derived from a number of PC system BIOS'es. The intent here is to
13 * provide very primitive video support, before an EGA/VGA BIOS installs its
14 * own interrupt vector. Here, "Ignored" calls should remain so. "Not
15 * Implemented" denotes functionality that can be implemented should the need
16 * arise. What are "Not Implemented" throughout are video memory accesses.
17 * Also, very little input validity checking is done here.
19 int int42_handler()
21 #if 0
22 if (verbose && X86_AH != 0x0e) {
23 printf("int%x\n", current->num);
24 x86emu_dump_xregs();
27 switch (X86_AH) {
28 case 0x00:
29 /* Set Video Mode */
30 /* Enter: AL = video mode number */
31 /* Leave: Nothing */
32 /* Implemented (except for clearing the screen) */
33 { /* Localise */
34 int i;
35 u16 ioport, int1d, regvals, tmp;
36 u8 mode, cgamode, cgacolour;
39 * Ignore all mode numbers but 0x00-0x13. Some systems also ignore
40 * 0x0B and 0x0C, but don't do that here.
42 if (X86_AL > 0x13)
43 break;
46 * You didn't think that was really the mode set, did you? There
47 * are only so many slots in the video parameter table...
49 mode = X86_AL;
50 ioport = 0x03D4;
51 switch (MEM_RB(0x0410) & 0x30) {
52 case 0x30: /* MDA */
53 mode = 0x07; /* Force mode to 0x07 */
54 ioport = 0x03B4;
55 break;
56 case 0x10: /* CGA 40x25 */
57 if (mode >= 0x07)
58 mode = 0x01;
59 break;
60 case 0x20: /* CGA 80x25 (MCGA?) */
61 if (mode >= 0x07)
62 mode = 0x03;
63 break;
64 case 0x00: /* EGA/VGA */
65 if (mode >= 0x07) /* Don't try MDA timings */
66 mode = 0x01; /* !?!?! */
67 break;
70 /* Locate data in video parameter table */
71 int1d = MEM_RW(0x1d << 2);
72 regvals = ((mode >> 1) << 4) + int1d;
73 cgacolour = 0x30;
74 if (mode == 0x06) {
75 regvals -= 0x10;
76 cgacolour = 0x3F;
79 /** Update BIOS Data Area **/
81 /* Video mode */
82 MEM_WB(0x0449, mode);
84 /* Columns */
85 tmp = MEM_RB(mode + int1d + 0x48);
86 MEM_WW(0x044A, tmp);
88 /* Page length */
89 tmp = MEM_RW((mode & 0x06) + int1d + 0x40);
90 MEM_WW(0x044C, tmp);
92 /* Start Address */
93 MEM_WW(0x044E, 0);
95 /* Cursor positions, one for each display page */
96 for (i = 0x0450; i < 0x0460; i += 2)
97 MEM_WW(i, 0);
99 /* Cursor start & end scanlines */
100 tmp = MEM_RB(regvals + 0x0B);
101 MEM_WB(0x0460, tmp);
102 tmp = MEM_RB(regvals + 0x0A);
103 MEM_WB(0x0461, tmp);
105 /* Current display page number */
106 MEM_WB(0x0462, 0);
108 /* CRTC I/O address */
109 MEM_WW(0x0463, ioport);
111 /* CGA Mode register value */
112 cgamode = MEM_RB(mode + int1d + 0x50);
113 MEM_WB(0x0465, cgamode);
115 /* CGA Colour register value */
116 MEM_WB(0x0466, cgacolour);
118 /* Rows */
119 MEM_WB(0x0484, (25 - 1));
121 /* Programme the mode */
122 outb(ioport + 4, cgamode & 0x37); /* Turn off screen */
123 for (i = 0; i < 0x10; i++) {
124 tmp = MEM_RB(regvals + i);
125 outb(ioport, i);
126 outb(ioport + 1, tmp);
128 outb(ioport + 5, cgacolour); /* Select colour mode */
129 outb(ioport + 4, cgamode); /* Turn on screen */
131 break;
133 case 0x01:
134 /* Set Cursor Type */
135 /* Enter: CH = starting line for cursor */
136 /* CL = ending line for cursor */
137 /* Leave: Nothing */
138 /* Implemented */
139 { /* Localise */
140 u16 ioport = MEM_RW(0x0463);
142 MEM_WB(0x0460, X86_CL);
143 MEM_WB(0x0461, X86_CH);
145 outb(ioport, 0x0A);
146 outb(ioport + 1, X86_CH);
147 outb(ioport, 0x0B);
148 outb(ioport + 1, X86_CL);
150 break;
152 case 0x02:
153 /* Set Cursor Position */
154 /* Enter: BH = display page number */
155 /* DH = row */
156 /* DL = column */
157 /* Leave: Nothing */
158 /* Implemented */
159 { /* Localise */
160 u16 offset, ioport;
162 MEM_WB((X86_BH << 1) + 0x0450, X86_DL);
163 MEM_WB((X86_BH << 1) + 0x0451, X86_DH);
165 if (X86_BH != MEM_RB(0x0462))
166 break;
168 offset = (X86_DH * MEM_RW(0x044A)) + X86_DL;
169 offset += MEM_RW(0x044E) << 1;
171 ioport = MEM_RW(0x0463);
172 outb(ioport, 0x0E);
173 outb(ioport + 1, offset >> 8);
174 outb(ioport, 0x0F);
175 outb(ioport + 1, offset & 0xFF);
177 break;
179 case 0x03:
180 /* Get Cursor Position */
181 /* Enter: BH = display page number */
182 /* Leave: CH = starting line for cursor */
183 /* CL = ending line for cursor */
184 /* DH = row */
185 /* DL = column */
186 /* Implemented */
187 { /* Localise */
188 X86_CL = MEM_RB(0x0460);
189 X86_CH = MEM_RB(0x0461);
190 X86_DL = MEM_RB((X86_BH << 1) + 0x0450);
191 X86_DH = MEM_RB((X86_BH << 1) + 0x0451);
193 break;
195 case 0x04:
196 /* Get Light Pen Position */
197 /* Enter: Nothing */
198 /* Leave: AH = 0x01 (down/triggered) or 0x00 (not) */
199 /* BX = pixel column */
200 /* CX = pixel row */
201 /* DH = character row */
202 /* DL = character column */
203 /* Not Implemented */
204 { /* Localise */
205 printf("int%x - Get Light Pen Position. "
206 "Function not implemented.\n", current->num);
207 x86emu_dump_xregs();
208 X86_AH = X86_BX = X86_CX = X86_DX = 0;
210 break;
212 case 0x05:
213 /* Set Display Page */
214 /* Enter: AL = display page number */
215 /* Leave: Nothing */
216 /* Implemented */
217 { /* Localise */
218 u16 start, ioport = MEM_RW(0x0463);
219 u8 x, y;
221 /* Calculate new start address */
222 MEM_WB(0x0462, X86_AL);
223 start = X86_AL * MEM_RW(0x044C);
224 MEM_WW(0x044E, start);
225 start <<= 1;
227 /* Update start address */
228 outb(ioport, 0x0C);
229 outb(ioport + 1, start >> 8);
230 outb(ioport, 0x0D);
231 outb(ioport + 1, start & 0xFF);
233 /* Switch cursor position */
234 y = MEM_RB((X86_AL << 1) + 0x0450);
235 x = MEM_RB((X86_AL << 1) + 0x0451);
236 start += (y * MEM_RW(0x044A)) + x;
238 /* Update cursor position */
239 outb(ioport, 0x0E);
240 outb(ioport + 1, start >> 8);
241 outb(ioport, 0x0F);
242 outb(ioport + 1, start & 0xFF);
244 break;
246 case 0x06:
247 /* Initialise or Scroll Window Up */
248 /* Enter: AL = lines to scroll up */
249 /* BH = attribute for blank */
250 /* CH = upper y of window */
251 /* CL = left x of window */
252 /* DH = lower y of window */
253 /* DL = right x of window */
254 /* Leave: Nothing */
255 /* Not Implemented */
256 { /* Localise */
257 printf("int%x: Initialise or Scroll Window Up - "
258 "Function not implemented.\n", current->num);
259 x86emu_dump_xregs();
261 break;
263 case 0x07:
264 /* Initialise or Scroll Window Down */
265 /* Enter: AL = lines to scroll down */
266 /* BH = attribute for blank */
267 /* CH = upper y of window */
268 /* CL = left x of window */
269 /* DH = lower y of window */
270 /* DL = right x of window */
271 /* Leave: Nothing */
272 /* Not Implemented */
273 { /* Localise */
274 printf("int%x: Initialise or Scroll Window Down - "
275 "Function not implemented.\n", current->num);
276 x86emu_dump_xregs();
279 break;
281 case 0x08:
282 /* Read Character and Attribute at Cursor */
283 /* Enter: BH = display page number */
284 /* Leave: AH = attribute */
285 /* AL = character */
286 /* Not Implemented */
287 { /* Localise */
288 printf
289 ("int%x: Read Character and Attribute at Cursor - "
290 "Function not implemented.\n", current->num);
291 x86emu_dump_xregs();
293 X86_AX = 0;
295 break;
297 case 0x09:
298 /* Write Character and Attribute at Cursor */
299 /* Enter: AL = character */
300 /* BH = display page number */
301 /* BL = attribute (text) or colour (graphics) */
302 /* CX = replication count */
303 /* Leave: Nothing */
304 /* Not Implemented */
305 { /* Localise */
306 printf
307 ("int%x: Write Character and Attribute at Cursor - "
308 "Function not implemented.\n", current->num);
309 x86emu_dump_xregs();
312 break;
314 case 0x0a:
315 /* Write Character at Cursor */
316 /* Enter: AL = character */
317 /* BH = display page number */
318 /* BL = colour */
319 /* CX = replication count */
320 /* Leave: Nothing */
321 /* Not Implemented */
322 { /* Localise */
323 printf("int%x: Write Character at Cursor - "
324 "Function not implemented.\n", current->num);
325 x86emu_dump_xregs();
328 break;
330 case 0x0b:
331 /* Set Palette, Background or Border */
332 /* Enter: BH = 0x00 or 0x01 */
333 /* BL = colour or palette (respectively) */
334 /* Leave: Nothing */
335 /* Implemented */
336 { /* Localise */
337 u16 ioport = MEM_RW(0x0463) + 5;
338 u8 cgacolour = MEM_RB(0x0466);
340 if (X86_BH) {
341 cgacolour &= 0xDF;
342 cgacolour |= (X86_BL & 0x01) << 5;
343 } else {
344 cgacolour &= 0xE0;
345 cgacolour |= X86_BL & 0x1F;
348 MEM_WB(0x0466, cgacolour);
349 outb(ioport, cgacolour);
351 break;
353 case 0x0c:
354 /* Write Graphics Pixel */
355 /* Enter: AL = pixel value */
356 /* BH = display page number */
357 /* CX = column */
358 /* DX = row */
359 /* Leave: Nothing */
360 /* Not Implemented */
361 { /* Localise */
362 printf("int%x: Write Graphics Pixel - "
363 "Function not implemented.\n", current->num);
364 x86emu_dump_xregs();
367 break;
369 case 0x0d:
370 /* Read Graphics Pixel */
371 /* Enter: BH = display page number */
372 /* CX = column */
373 /* DX = row */
374 /* Leave: AL = pixel value */
375 /* Not Implemented */
376 { /* Localise */
377 printf("int%x: Write Graphics Pixel - "
378 "Function not implemented.\n", current->num);
379 x86emu_dump_xregs();
381 X86_AL = 0;
384 break;
386 case 0x0e:
387 /* Write Character in Teletype Mode */
388 /* Enter: AL = character */
389 /* BH = display page number */
390 /* BL = foreground colour */
391 /* Leave: Nothing */
392 /* Not Implemented */
393 /* WARNING: Emulation of BEL characters will require */
394 /* emulation of RTC and PC speaker I/O. */
395 /* Also, this recurses through int 0x10 */
396 /* which might or might not have been */
397 /* installed yet. */
398 { /* Localise */
399 #ifdef PARANOID
400 printf("int%x: Write Character in Teletype Mode - "
401 "Function not implemented.\n", current->num);
402 x86emu_dump_xregs();
403 #endif
404 printf("%c", X86_AL);
406 break;
408 case 0x0f:
409 /* Get Video Mode */
410 /* Enter: Nothing */
411 /* Leave: AH = number of columns */
412 /* AL = video mode number */
413 /* BH = display page number */
414 /* Implemented */
415 { /* Localise */
416 X86_AH = MEM_RW(0x044A);
417 X86_AL = MEM_RB(0x0449);
418 X86_BH = MEM_RB(0x0462);
420 break;
422 case 0x10:
423 /* Colour Control (subfunction in AL) */
424 /* Enter: Various */
425 /* Leave: Various */
426 /* Ignored */
427 break;
429 case 0x11:
430 /* Font Control (subfunction in AL) */
431 /* Enter: Various */
432 /* Leave: Various */
433 /* Ignored */
434 break;
436 case 0x12:
437 /* Miscellaneous (subfunction in BL) */
438 /* Enter: Various */
439 /* Leave: Various */
440 /* Ignored. Previous code here optionally allowed */
441 /* the enabling and disabling of VGA, but no system */
442 /* BIOS I've come across actually implements it. */
443 break;
445 case 0x13:
446 /* Write String in Teletype Mode */
447 /* Enter: AL = write mode */
448 /* BL = attribute (if (AL & 0x02) == 0) */
449 /* CX = string length */
450 /* DH = row */
451 /* DL = column */
452 /* ES:BP = string segment:offset */
453 /* Leave: Nothing */
454 /* Not Implemented */
455 /* WARNING: Emulation of BEL characters will require */
456 /* emulation of RTC and PC speaker I/O. */
457 /* Also, this recurses through int 0x10 */
458 /* which might or might not have been */
459 /* installed yet. */
460 { /* Localise */
461 printf("int%x: Write String in Teletype Mode - "
462 "Function not implemented.\n", current->num);
463 x86emu_dump_xregs();
466 break;
468 default:
469 /* Various extensions */
470 /* Enter: Various */
471 /* Leave: Various */
472 /* Ignored */
473 break;
475 #endif
476 return 1;
478 #endif