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