First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / int10 / xf86int10.c
blobd74643eaf681196deb577794fde15fb005348f65
1 /*
2 * XFree86 int10 module
3 * execute BIOS int 10h calls in x86 real mode environment
4 * Copyright 1999 Egbert Eich
5 */
7 #ifdef HAVE_XORG_CONFIG_H
8 #include <xorg-config.h>
9 #endif
11 #include "xf86.h"
12 #include "compiler.h"
13 #define _INT10_PRIVATE
14 #include "xf86int10.h"
15 #include "int10Defines.h"
17 #define REG pInt
19 xf86Int10InfoPtr Int10Current = NULL;
21 static int int1A_handler(xf86Int10InfoPtr pInt);
22 #ifndef _PC
23 static int int42_handler(xf86Int10InfoPtr pInt);
24 #endif
25 static int intE6_handler(xf86Int10InfoPtr pInt);
26 static PCITAG findPci(xf86Int10InfoPtr pInt, unsigned short bx);
27 static CARD32 pciSlotBX(pciVideoPtr pvp);
29 int
30 int_handler(xf86Int10InfoPtr pInt)
32 int num = pInt->num;
33 int ret = 0;
35 switch (num) {
36 #ifndef _PC
37 case 0x10:
38 case 0x42:
39 case 0x6D:
40 if (getIntVect(pInt, num) == I_S_DEFAULT_INT_VECT)
41 ret = int42_handler(pInt);
42 break;
43 #endif
44 case 0x1A:
45 ret = int1A_handler(pInt);
46 break;
47 case 0xe6:
48 ret = intE6_handler(pInt);
49 break;
50 default:
51 break;
54 if (!ret)
55 ret = run_bios_int(num, pInt);
57 if (!ret) {
58 xf86DrvMsg(pInt->scrnIndex, X_ERROR,
59 "Halting on int 0x%2.2x!\n", num);
60 dump_registers(pInt);
61 stack_trace(pInt);
64 return ret;
67 #ifndef _PC
69 * This is derived from a number of PC system BIOS'es. The intent here is to
70 * provide very primitive video support, before an EGA/VGA BIOS installs its
71 * own interrupt vector. Here, "Ignored" calls should remain so. "Not
72 * Implemented" denotes functionality that can be implemented should the need
73 * arise. What are "Not Implemented" throughout are video memory accesses.
74 * Also, very little input validity checking is done here.
76 static int
77 int42_handler(xf86Int10InfoPtr pInt)
79 switch (X86_AH) {
80 case 0x00:
81 /* Set Video Mode */
82 /* Enter: AL = video mode number */
83 /* Leave: Nothing */
84 /* Implemented (except for clearing the screen) */
85 { /* Localise */
86 IOADDRESS ioport;
87 int i;
88 CARD16 int1d, regvals, tmp;
89 CARD8 mode, cgamode, cgacolour;
92 * Ignore all mode numbers but 0x00-0x13. Some systems also ignore
93 * 0x0B and 0x0C, but don't do that here.
95 if (X86_AL > 0x13)
96 break;
99 * You didn't think that was really the mode set, did you? There
100 * are only so many slots in the video parameter table...
102 mode = X86_AL;
103 ioport = 0x03D4;
104 switch (MEM_RB(pInt, 0x0410) & 0x30) {
105 case 0x30: /* MDA */
106 mode = 0x07; /* Force mode to 0x07 */
107 ioport = 0x03B4;
108 break;
109 case 0x10: /* CGA 40x25 */
110 if (mode >= 0x07)
111 mode = 0x01;
112 break;
113 case 0x20: /* CGA 80x25 (MCGA?) */
114 if (mode >= 0x07)
115 mode = 0x03;
116 break;
117 case 0x00: /* EGA/VGA */
118 if (mode >= 0x07) /* Don't try MDA timings */
119 mode = 0x01; /* !?!?! */
120 break;
123 /* Locate data in video parameter table */
124 int1d = MEM_RW(pInt, 0x1d << 2);
125 regvals = ((mode >> 1) << 4) + int1d;
126 cgacolour = 0x30;
127 if (mode == 0x06) {
128 regvals -= 0x10;
129 cgacolour = 0x3F;
132 /** Update BIOS Data Area **/
134 /* Video mode */
135 MEM_WB(pInt, 0x0449, mode);
137 /* Columns */
138 tmp = MEM_RB(pInt, mode + int1d + 0x48);
139 MEM_WW(pInt, 0x044A, tmp);
141 /* Page length */
142 tmp = MEM_RW(pInt, (mode & 0x06) + int1d + 0x40);
143 MEM_WW(pInt, 0x044C, tmp);
145 /* Start Address */
146 MEM_WW(pInt, 0x044E, 0);
148 /* Cursor positions, one for each display page */
149 for (i = 0x0450; i < 0x0460; i += 2)
150 MEM_WW(pInt, i, 0);
152 /* Cursor start & end scanlines */
153 tmp = MEM_RB(pInt, regvals + 0x0B);
154 MEM_WB(pInt, 0x0460, tmp);
155 tmp = MEM_RB(pInt, regvals + 0x0A);
156 MEM_WB(pInt, 0x0461, tmp);
158 /* Current display page number */
159 MEM_WB(pInt, 0x0462, 0);
161 /* CRTC I/O address */
162 MEM_WW(pInt, 0x0463, ioport);
164 /* CGA Mode register value */
165 cgamode = MEM_RB(pInt, mode + int1d + 0x50);
166 MEM_WB(pInt, 0x0465, cgamode);
168 /* CGA Colour register value */
169 MEM_WB(pInt, 0x0466, cgacolour);
171 /* Rows */
172 MEM_WB(pInt, 0x0484, (25 - 1));
174 /* Remap I/O port number into its domain */
175 ioport += pInt->ioBase;
177 /* Programme the mode */
178 outb(ioport + 4, cgamode & 0x37); /* Turn off screen */
179 for (i = 0; i < 0x10; i++) {
180 tmp = MEM_RB(pInt, regvals + i);
181 outb(ioport, i);
182 outb(ioport + 1, tmp);
184 outb(ioport + 5, cgacolour); /* Select colour mode */
185 outb(ioport + 4, cgamode); /* Turn on screen */
187 break;
189 case 0x01:
190 /* Set Cursor Type */
191 /* Enter: CH = starting line for cursor */
192 /* CL = ending line for cursor */
193 /* Leave: Nothing */
194 /* Implemented */
195 { /* Localise */
196 IOADDRESS ioport = MEM_RW(pInt, 0x0463) + pInt->ioBase;
198 MEM_WB(pInt, 0x0460, X86_CL);
199 MEM_WB(pInt, 0x0461, X86_CH);
201 outb(ioport, 0x0A);
202 outb(ioport + 1, X86_CH);
203 outb(ioport, 0x0B);
204 outb(ioport + 1, X86_CL);
206 break;
208 case 0x02:
209 /* Set Cursor Position */
210 /* Enter: BH = display page number */
211 /* DH = row */
212 /* DL = column */
213 /* Leave: Nothing */
214 /* Implemented */
215 { /* Localise */
216 IOADDRESS ioport;
217 CARD16 offset;
219 MEM_WB(pInt, (X86_BH << 1) + 0x0450, X86_DL);
220 MEM_WB(pInt, (X86_BH << 1) + 0x0451, X86_DH);
222 if (X86_BH != MEM_RB(pInt, 0x0462))
223 break;
225 offset = (X86_DH * MEM_RW(pInt, 0x044A)) + X86_DL;
226 offset += MEM_RW(pInt, 0x044E) << 1;
228 ioport = MEM_RW(pInt, 0x0463) + pInt->ioBase;
229 outb(ioport, 0x0E);
230 outb(ioport + 1, offset >> 8);
231 outb(ioport, 0x0F);
232 outb(ioport + 1, offset & 0xFF);
234 break;
236 case 0x03:
237 /* Get Cursor Position */
238 /* Enter: BH = display page number */
239 /* Leave: CH = starting line for cursor */
240 /* CL = ending line for cursor */
241 /* DH = row */
242 /* DL = column */
243 /* Implemented */
244 { /* Localise */
245 X86_CL = MEM_RB(pInt, 0x0460);
246 X86_CH = MEM_RB(pInt, 0x0461);
247 X86_DL = MEM_RB(pInt, (X86_BH << 1) + 0x0450);
248 X86_DH = MEM_RB(pInt, (X86_BH << 1) + 0x0451);
250 break;
252 case 0x04:
253 /* Get Light Pen Position */
254 /* Enter: Nothing */
255 /* Leave: AH = 0x01 (down/triggered) or 0x00 (not) */
256 /* BX = pixel column */
257 /* CX = pixel row */
258 /* DH = character row */
259 /* DL = character column */
260 /* Not Implemented */
261 { /* Localise */
262 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
263 "int 0x%2.2x(AH=0x04) -- Get Light Pen Position\n", pInt->num);
264 if (xf86GetVerbosity() > 3) {
265 dump_registers(pInt);
266 stack_trace(pInt);
268 X86_AH = X86_BX = X86_CX = X86_DX = 0;
270 break;
272 case 0x05:
273 /* Set Display Page */
274 /* Enter: AL = display page number */
275 /* Leave: Nothing */
276 /* Implemented */
277 { /* Localise */
278 IOADDRESS ioport = MEM_RW(pInt, 0x0463) + pInt->ioBase;
279 CARD16 start;
280 CARD8 x, y;
282 /* Calculate new start address */
283 MEM_WB(pInt, 0x0462, X86_AL);
284 start = X86_AL * MEM_RW(pInt, 0x044C);
285 MEM_WW(pInt, 0x044E, start);
286 start <<= 1;
288 /* Update start address */
289 outb(ioport, 0x0C);
290 outb(ioport + 1, start >> 8);
291 outb(ioport, 0x0D);
292 outb(ioport + 1, start & 0xFF);
294 /* Switch cursor position */
295 y = MEM_RB(pInt, (X86_AL << 1) + 0x0450);
296 x = MEM_RB(pInt, (X86_AL << 1) + 0x0451);
297 start += (y * MEM_RW(pInt, 0x044A)) + x;
299 /* Update cursor position */
300 outb(ioport, 0x0E);
301 outb(ioport + 1, start >> 8);
302 outb(ioport, 0x0F);
303 outb(ioport + 1, start & 0xFF);
305 break;
307 case 0x06:
308 /* Initialise or Scroll Window Up */
309 /* Enter: AL = lines to scroll up */
310 /* BH = attribute for blank */
311 /* CH = upper y of window */
312 /* CL = left x of window */
313 /* DH = lower y of window */
314 /* DL = right x of window */
315 /* Leave: Nothing */
316 /* Not Implemented */
317 { /* Localise */
318 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
319 "int 0x%2.2x(AH=0x06) -- Initialise or Scroll Window Up\n",
320 pInt->num);
321 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
322 " AL=0x%2.2x, BH=0x%2.2x,"
323 " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
324 X86_AL, X86_BH, X86_CH, X86_CL, X86_DH, X86_DL);
325 if (xf86GetVerbosity() > 3) {
326 dump_registers(pInt);
327 stack_trace(pInt);
330 break;
332 case 0x07:
333 /* Initialise or Scroll Window Down */
334 /* Enter: AL = lines to scroll down */
335 /* BH = attribute for blank */
336 /* CH = upper y of window */
337 /* CL = left x of window */
338 /* DH = lower y of window */
339 /* DL = right x of window */
340 /* Leave: Nothing */
341 /* Not Implemented */
342 { /* Localise */
343 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
344 "int 0x%2.2x(AH=0x07) -- Initialise or Scroll Window Down\n",
345 pInt->num);
346 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
347 " AL=0x%2.2x, BH=0x%2.2x,"
348 " CH=0x%2.2x, CL=0x%2.2x, DH=0x%2.2x, DL=0x%2.2x\n",
349 X86_AL, X86_BH, X86_CH, X86_CL, X86_DH, X86_DL);
350 if (xf86GetVerbosity() > 3) {
351 dump_registers(pInt);
352 stack_trace(pInt);
355 break;
357 case 0x08:
358 /* Read Character and Attribute at Cursor */
359 /* Enter: BH = display page number */
360 /* Leave: AH = attribute */
361 /* AL = character */
362 /* Not Implemented */
363 { /* Localise */
364 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
365 "int 0x%2.2x(AH=0x08) -- Read Character and Attribute at"
366 " Cursor\n", pInt->num);
367 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
368 "BH=0x%2.2x\n", X86_BH);
369 if (xf86GetVerbosity() > 3) {
370 dump_registers(pInt);
371 stack_trace(pInt);
373 X86_AX = 0;
375 break;
377 case 0x09:
378 /* Write Character and Attribute at Cursor */
379 /* Enter: AL = character */
380 /* BH = display page number */
381 /* BL = attribute (text) or colour (graphics) */
382 /* CX = replication count */
383 /* Leave: Nothing */
384 /* Not Implemented */
385 { /* Localise */
386 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
387 "int 0x%2.2x(AH=0x09) -- Write Character and Attribute at"
388 " Cursor\n", pInt->num);
389 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
390 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
391 X86_AL, X86_BH, X86_BL, X86_CX);
392 if (xf86GetVerbosity() > 3) {
393 dump_registers(pInt);
394 stack_trace(pInt);
397 break;
399 case 0x0a:
400 /* Write Character at Cursor */
401 /* Enter: AL = character */
402 /* BH = display page number */
403 /* BL = colour */
404 /* CX = replication count */
405 /* Leave: Nothing */
406 /* Not Implemented */
407 { /* Localise */
408 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
409 "int 0x%2.2x(AH=0x0A) -- Write Character at Cursor\n",
410 pInt->num);
411 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
412 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x\n",
413 X86_AL, X86_BH, X86_BL, X86_CX);
414 if (xf86GetVerbosity() > 3) {
415 dump_registers(pInt);
416 stack_trace(pInt);
419 break;
421 case 0x0b:
422 /* Set Palette, Background or Border */
423 /* Enter: BH = 0x00 or 0x01 */
424 /* BL = colour or palette (respectively) */
425 /* Leave: Nothing */
426 /* Implemented */
427 { /* Localise */
428 IOADDRESS ioport = MEM_RW(pInt, 0x0463) + 5 + pInt->ioBase;
429 CARD8 cgacolour = MEM_RB(pInt, 0x0466);
431 if (X86_BH) {
432 cgacolour &= 0xDF;
433 cgacolour |= (X86_BL & 0x01) << 5;
434 } else {
435 cgacolour &= 0xE0;
436 cgacolour |= X86_BL & 0x1F;
439 MEM_WB(pInt, 0x0466, cgacolour);
440 outb(ioport, cgacolour);
442 break;
444 case 0x0c:
445 /* Write Graphics Pixel */
446 /* Enter: AL = pixel value */
447 /* BH = display page number */
448 /* CX = column */
449 /* DX = row */
450 /* Leave: Nothing */
451 /* Not Implemented */
452 { /* Localise */
453 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
454 "int 0x%2.2x(AH=0x0C) -- Write Graphics Pixel\n", pInt->num);
455 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
456 "AL=0x%2.2x, BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n",
457 X86_AL, X86_BH, X86_CX, X86_DX);
458 if (xf86GetVerbosity() > 3) {
459 dump_registers(pInt);
460 stack_trace(pInt);
463 break;
465 case 0x0d:
466 /* Read Graphics Pixel */
467 /* Enter: BH = display page number */
468 /* CX = column */
469 /* DX = row */
470 /* Leave: AL = pixel value */
471 /* Not Implemented */
472 { /* Localise */
473 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
474 "int 0x%2.2x(AH=0x0D) -- Read Graphics Pixel\n", pInt->num);
475 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
476 "BH=0x%2.2x, CX=0x%4.4x, DX=0x%4.4x\n",
477 X86_BH, X86_CX, X86_DX);
478 if (xf86GetVerbosity() > 3) {
479 dump_registers(pInt);
480 stack_trace(pInt);
482 X86_AL = 0;
484 break;
486 case 0x0e:
487 /* Write Character in Teletype Mode */
488 /* Enter: AL = character */
489 /* BH = display page number */
490 /* BL = foreground colour */
491 /* Leave: Nothing */
492 /* Not Implemented */
493 /* WARNING: Emulation of BEL characters will require */
494 /* emulation of RTC and PC speaker I/O. */
495 /* Also, this recurses through int 0x10 */
496 /* which might or might not have been */
497 /* installed yet. */
498 { /* Localise */
499 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
500 "int 0x%2.2x(AH=0x0E) -- Write Character in Teletype Mode\n",
501 pInt->num);
502 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
503 "AL=0x%2.2x, BH=0x%2.2x, BL=0x%2.2x\n",
504 X86_AL, X86_BH, X86_BL);
505 if (xf86GetVerbosity() > 3) {
506 dump_registers(pInt);
507 stack_trace(pInt);
510 break;
512 case 0x0f:
513 /* Get Video Mode */
514 /* Enter: Nothing */
515 /* Leave: AH = number of columns */
516 /* AL = video mode number */
517 /* BH = display page number */
518 /* Implemented */
519 { /* Localise */
520 X86_AH = MEM_RW(pInt, 0x044A);
521 X86_AL = MEM_RB(pInt, 0x0449);
522 X86_BH = MEM_RB(pInt, 0x0462);
524 break;
526 case 0x10:
527 /* Colour Control (subfunction in AL) */
528 /* Enter: Various */
529 /* Leave: Various */
530 /* Ignored */
531 break;
533 case 0x11:
534 /* Font Control (subfunction in AL) */
535 /* Enter: Various */
536 /* Leave: Various */
537 /* Ignored */
538 break;
540 case 0x12:
541 /* Miscellaneous (subfunction in BL) */
542 /* Enter: Various */
543 /* Leave: Various */
544 /* Ignored. Previous code here optionally allowed */
545 /* the enabling and disabling of VGA, but no system */
546 /* BIOS I've come across actually implements it. */
547 break;
549 case 0x13:
550 /* Write String in Teletype Mode */
551 /* Enter: AL = write mode */
552 /* BL = attribute (if (AL & 0x02) == 0) */
553 /* CX = string length */
554 /* DH = row */
555 /* DL = column */
556 /* ES:BP = string segment:offset */
557 /* Leave: Nothing */
558 /* Not Implemented */
559 /* WARNING: Emulation of BEL characters will require */
560 /* emulation of RTC and PC speaker I/O. */
561 /* Also, this recurses through int 0x10 */
562 /* which might or might not have been */
563 /* installed yet. */
564 { /* Localise */
565 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
566 "int 0x%2.2x(AH=0x13) -- Write String in Teletype Mode\n",
567 pInt->num);
568 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 3,
569 "AL=0x%2.2x, BL=0x%2.2x, CX=0x%4.4x,"
570 " DH=0x%2.2x, DL=0x%2.2x, ES:BP=0x%4.4x:0x%4.4x\n",
571 X86_AL, X86_BL, X86_CX, X86_DH, X86_DL, X86_ES, X86_BP);
572 if (xf86GetVerbosity() > 3) {
573 dump_registers(pInt);
574 stack_trace(pInt);
577 break;
579 default:
580 /* Various extensions */
581 /* Enter: Various */
582 /* Leave: Various */
583 /* Ignored */
584 break;
587 return 1;
589 #endif
591 #define SUCCESSFUL 0x00
592 #define DEVICE_NOT_FOUND 0x86
593 #define BAD_REGISTER_NUMBER 0x87
595 static int
596 int1A_handler(xf86Int10InfoPtr pInt)
598 PCITAG tag;
599 pciVideoPtr pvp;
601 if (!(pvp = xf86GetPciInfoForEntity(pInt->entityIndex)))
602 return 0; /* oops */
604 #ifdef PRINT_INT
605 ErrorF("int 0x1a: ax=0x%x bx=0x%x cx=0x%x dx=0x%x di=0x%x es=0x%x\n",
606 X86_EAX, X86_EBX, X86_ECX, X86_EDX, X86_EDI, X86_ESI);
607 #endif
608 switch (X86_AX) {
609 case 0xb101:
610 X86_EAX &= 0xFF00; /* no config space/special cycle support */
611 X86_EDX = 0x20494350; /* " ICP" */
612 X86_EBX = 0x0210; /* Version 2.10 */
613 X86_ECX &= 0xFF00;
614 X86_ECX |= (pciNumBuses & 0xFF); /* Max bus number in system */
615 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
616 #ifdef PRINT_INT
617 ErrorF("ax=0x%x dx=0x%x bx=0x%x cx=0x%x flags=0x%x\n",
618 X86_EAX, X86_EDX, X86_EBX, X86_ECX, X86_EFLAGS);
619 #endif
620 return 1;
621 case 0xb102:
622 if (X86_DX == pvp->vendor && X86_CX == pvp->chipType && X86_ESI == 0) {
623 X86_EAX = X86_AL | (SUCCESSFUL << 8);
624 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
625 X86_EBX = pciSlotBX(pvp);
627 #ifdef SHOW_ALL_DEVICES
628 else
629 if ((pvp = xf86FindPciDeviceVendor(X86_EDX, X86_ECX, X86_ESI, pvp))) {
630 X86_EAX = X86_AL | (SUCCESSFUL << 8);
631 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
632 X86_EBX = pciSlotBX(pvp);
634 #endif
635 else {
636 X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
637 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
639 #ifdef PRINT_INT
640 ErrorF("ax=0x%x bx=0x%x flags=0x%x\n", X86_EAX, X86_EBX, X86_EFLAGS);
641 #endif
642 return 1;
643 case 0xb103:
644 if (X86_CL == pvp->interface &&
645 X86_CH == pvp->subclass &&
646 ((X86_ECX & 0xFFFF0000) >> 16) == pvp->class) {
647 X86_EAX = X86_AL | (SUCCESSFUL << 8);
648 X86_EBX = pciSlotBX(pvp);
649 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
651 #ifdef SHOW_ALL_DEVICES
652 else if ((pvp = xf86FindPciClass(X86_CL, X86_CH,
653 (X86_ECX & 0xffff0000) >> 16,
654 X86_ESI, pvp))) {
655 X86_EAX = X86_AL | (SUCCESSFUL << 8);
656 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
657 X86_EBX = pciSlotBX(pvp);
659 #endif
660 else {
661 X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
662 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
664 #ifdef PRINT_INT
665 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
666 #endif
667 return 1;
668 case 0xb108:
669 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
670 X86_CL = pciReadByte(tag, X86_EDI);
671 X86_EAX = X86_AL | (SUCCESSFUL << 8);
672 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
673 } else {
674 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
675 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
677 #ifdef PRINT_INT
678 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
679 #endif
680 return 1;
681 case 0xb109:
682 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
683 X86_CX = pciReadWord(tag, X86_EDI);
684 X86_EAX = X86_AL | (SUCCESSFUL << 8);
685 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
686 } else {
687 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
688 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
690 #ifdef PRINT_INT
691 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
692 #endif
693 return 1;
694 case 0xb10a:
695 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
696 X86_ECX = pciReadLong(tag, X86_EDI);
697 X86_EAX = X86_AL | (SUCCESSFUL << 8);
698 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
699 } else {
700 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
701 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
703 #ifdef PRINT_INT
704 ErrorF("ax=0x%x cx=0x%x flags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
705 #endif
706 return 1;
707 case 0xb10b:
708 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
709 pciWriteByte(tag, X86_EDI, X86_CL);
710 X86_EAX = X86_AL | (SUCCESSFUL << 8);
711 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
712 } else {
713 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
714 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
716 #ifdef PRINT_INT
717 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
718 #endif
719 return 1;
720 case 0xb10c:
721 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
722 pciWriteWord(tag, X86_EDI, X86_CX);
723 X86_EAX = X86_AL | (SUCCESSFUL << 8);
724 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
725 } else {
726 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
727 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
729 #ifdef PRINT_INT
730 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
731 #endif
732 return 1;
733 case 0xb10d:
734 if ((tag = findPci(pInt, X86_EBX)) != PCI_NOT_FOUND) {
735 pciWriteLong(tag, X86_EDI, X86_ECX);
736 X86_EAX = X86_AL | (SUCCESSFUL << 8);
737 X86_EFLAGS &= ~((unsigned long)0x01); /* clear carry flag */
738 } else {
739 X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
740 X86_EFLAGS |= ((unsigned long)0x01); /* set carry flag */
742 #ifdef PRINT_INT
743 ErrorF("ax=0x%x flags=0x%x\n", X86_EAX, X86_EFLAGS);
744 #endif
745 return 1;
746 default:
747 xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
748 "int 0x1a subfunction\n");
749 dump_registers(pInt);
750 if (xf86GetVerbosity() > 3)
751 stack_trace(pInt);
752 return 0;
756 static PCITAG
757 findPci(xf86Int10InfoPtr pInt, unsigned short bx)
759 int bus = ((pInt->Tag >> 16) & ~0x00FF) | ((bx >> 8) & 0x00FF);
760 int dev = (bx >> 3) & 0x1F;
761 int func = bx & 0x7;
762 if (xf86IsPciDevPresent(bus, dev, func))
763 return pciTag(bus, dev, func);
764 return PCI_NOT_FOUND;
767 static CARD32
768 pciSlotBX(pciVideoPtr pvp)
770 return ((pvp->bus << 8) & 0x00FF00) | (pvp->device << 3) | (pvp->func);
774 * handle initialization
776 static int
777 intE6_handler(xf86Int10InfoPtr pInt)
779 pciVideoPtr pvp;
781 if ((pvp = xf86GetPciInfoForEntity(pInt->entityIndex)))
782 X86_AX = (pvp->bus << 8) | (pvp->device << 3) | (pvp->func & 0x7);
783 pushw(pInt, X86_CS);
784 pushw(pInt, X86_IP);
785 X86_CS = pInt->BIOSseg;
786 X86_EIP = 0x0003;
787 X86_ES = 0; /* standard pc es */
788 return 1;