2 * Copyright (c) 1992, 1993, 1996
3 * Berkeley Software Design, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Berkeley Software
18 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * BSDI int10.c,v 2.3 1996/04/08 19:32:40 bostic Exp
32 * $FreeBSD: src/usr.bin/doscmd/int10.c,v 1.3.2.2 2002/04/25 11:04:51 tg Exp $
33 * $DragonFly: src/usr.bin/doscmd/int10.c,v 1.2 2003/06/17 04:29:26 dillon Exp $
43 static int cursoremu
= 1;
46 int10(regcontext_t
*REGS
)
50 int saved_row
, saved_col
;
53 * Any call to the video BIOS is enough to reset the poll
54 * count on the keyboard.
59 case 0x00: /* Set display mode */
64 case 0x01: /* Define cursor */
72 /* Cursor emulation */
73 if (start
<= 3 && end
<= 3)
75 if (start
+ 2 >= end
) {
76 /* underline cursor */
77 start
= CharHeight
- 3;
81 if (start
<= 2 || end
< start
) {
87 if (start
> CharHeight
/ 2) {
88 /* half block cursor */
89 start
= CharHeight
/ 2;
92 out
: CursStart
= start
;
96 case 0x02: /* Position cursor */
101 case 0x03: /* Read cursor position */
111 debug(D_VIDEO
, "Select current display page %d\n", R_AL
);
113 case 0x06: /* initialize window/scroll text upward */
116 if (R_AL
== 0) /* clear screen */
118 tty_scroll(R_CH
, R_CL
,
122 case 0x07: /* initialize window/scroll text downward */
125 if (R_AL
== 0) /* clear screen */
127 tty_rscroll(R_CH
, R_CL
,
131 case 0x08: /* read character/attribute */
134 i
= tty_char(-1, -1);
137 case 0x09: /* write character/attribute */
140 tty_rwrite(R_CX
, R_AL
, R_BL
<< 8);
142 case 0x0a: /* write character */
145 debug(D_HALF
, "Int 10:0a: Write char: %02x\n", R_AL
);
146 tty_rwrite(R_CX
, R_AL
, -1);
148 case 0x0b: /* set border color */
151 video_setborder(R_BL
);
153 case 0x0c: /* write graphics pixel */
154 debug(D_VIDEO
, "Write graphics pixel at %d, %d\n", R_CX
, R_DX
);
156 case 0x0d: /* read graphics pixel */
157 debug(D_VIDEO
, "Read graphics pixel at %d, %d\n", R_CX
, R_DX
);
159 case 0x0e: /* write character */
162 case 0x0f: /* get current video mode */
163 R_AH
= DpyCols
; /* number of columns */
164 R_AL
= VideoMode
; /* active mode */
165 R_BH
= 0;/*ActivePage *//* display page */
171 case 0x00: /* Set single palette register */
172 palette
[R_BL
] = R_BH
;
175 case 0x01: /* Set overscan register */
176 VGA_ATC
[ATC_OverscanColor
] = R_BH
;
178 case 0x02: /* Set all palette registers */
179 addr
= (char *)MAKEPTR(R_ES
, R_DX
);
180 for (i
= 0; i
< 16; i
++)
181 palette
[i
] = *addr
++;
182 VGA_ATC
[ATC_OverscanColor
] = *addr
;
185 case 0x03: /* Enable/Disable blinking mode */
186 video_blink((R_BL
& 1) ? 1 : 0);
188 case 0x07: /* Get individual palette register */
189 R_BH
= palette
[R_BL
];
191 case 0x08: /* Read overscan register */
192 R_BH
= VGA_ATC
[ATC_OverscanColor
];
194 case 0x09: /* Read all palette registers */
195 addr
= (char *)MAKEPTR(R_ES
, R_DX
);
196 for (i
= 0; i
< 16; i
++)
197 *addr
++ = palette
[i
];
198 *addr
= VGA_ATC
[ATC_OverscanColor
];
200 case 0x10: /* Set individual DAC register */
201 dac_rgb
[R_BX
].red
= R_DH
& 0x3f;
202 dac_rgb
[R_BX
].green
= R_CH
& 0x3f;
203 dac_rgb
[R_BX
].blue
= R_CL
& 0x3f;
206 case 0x12: /* Set block of DAC registers */
207 addr
= (char *)MAKEPTR(R_ES
, R_DX
);
208 for (i
= R_BX
; i
< R_BX
+ R_CX
; i
++) {
209 dac_rgb
[i
].red
= *addr
++;
210 dac_rgb
[i
].green
= *addr
++;
211 dac_rgb
[i
].blue
= *addr
++;
215 case 0x13: /* Select video DAC color page */
218 VGA_ATC
[ATC_ModeCtrl
] |= (R_BH
& 0x01) << 7;
221 VGA_ATC
[ATC_ColorSelect
] = R_BH
& 0x0f;
224 debug(D_VIDEO
, "INT 10 10:13 "
225 "Bad value for BL: 0x%02x\n", R_BL
);
228 case 0x15: /* Read individual DAC register */
229 R_DH
= dac_rgb
[R_BX
].red
;
230 R_CH
= dac_rgb
[R_BX
].green
;
231 R_CL
= dac_rgb
[R_BX
].blue
;
233 case 0x17: /* Read block of DAC registers */
234 addr
= (char *)MAKEPTR(R_ES
, R_DX
);
235 for (i
= R_BX
; i
< R_BX
+ R_CX
; i
++) {
236 *addr
++ = dac_rgb
[i
].red
;
237 *addr
++ = dac_rgb
[i
].green
;
238 *addr
++ = dac_rgb
[i
].blue
;
241 case 0x18: /* Set PEL mask */
243 "INT 10 10:18 Set PEL mask (%02x)\n", R_BL
);
245 case 0x19: /* Read PEL mask */
246 debug(D_HALF
, "INT 10 10:19 Read PEL mask\n");
248 case 0x1a: /* Get video dac color-page state */
249 R_BH
= (VGA_ATC
[ATC_ModeCtrl
] & 0x80) >> 7;
250 R_BL
= VGA_ATC
[ATC_ColorSelect
];
252 case 0x1b: /* Perform gray-scale summing */
253 debug(D_HALF
, "Perform gray-scale summing\n");
256 unknown_int3(0x10, 0x10, R_AL
, REGS
);
262 case 0x00: /* Text-mode chargen: load user-specified
264 debug(D_VIDEO
, "Tried to load user defined font.\n");
266 case 0x01: /* Text-mode chargen: load ROM monochrome
268 debug(D_VIDEO
, "Tried to load 8x14 font.\n");
270 case 0x02: /* Text-mode chargen: load ROM 8x8 double-dot
272 debug(D_VIDEO
, "Tried to load 8x8 font.\n");
274 case 0x03: /* Text-mode chargen: set block specifier */
275 debug(D_VIDEO
, "Tried to activate character set\n");
277 case 0x04: /* Text-mode chargen: load ROM 8x16 character
279 debug(D_VIDEO
, "Tried to load 8x16 font.\n");
281 case 0x10: /* Text-mode chargen: load and activate
282 user-specified patterns */
284 "Tried to load and activate user defined font\n");
286 case 0x11: /* Text-mode chargen: load and activate ROM
287 monochrome patterns */
289 "Tried to load and activate 8x14 font.\n");
291 case 0x12: /* Text-mode chargen: load and activate ROM
292 8x8 double-dot patterns */
294 "Tried to load and activate 8x8 font.\n");
296 case 0x14: /* Text-mode chargen: load and activate ROM
297 8x16 character set */
299 "Tried to load and activate 8x16 font.\n");
301 case 0x20: /* Graph-mode chargen: set user 8x8 graphics
303 debug(D_VIDEO
, "Load second half of 8x8 char set\n");
305 case 0x21: /* Graph-mode chargen: set user graphics
307 debug(D_VIDEO
, "Install user defined char set\n");
309 case 0x22: /* Graph-mode chargen: set ROM 8x14 graphics
311 debug(D_VIDEO
, "Install 8x14 char set\n");
313 case 0x23: /* Graph-mode chargen: set ROM 8x8 double-dot
315 debug(D_VIDEO
, "Install 8x8 char set\n");
317 case 0x24: /* Graph-mode chargen: load 8x16 graphics
319 debug(D_VIDEO
, "Install 8x16 char set\n");
321 case 0x30: /* Get font information */
323 "INT 10 11:30 Request font address %02x\n", R_BH
);
328 PUTVEC(R_ES
, R_BP
, ivec
[0x1f]);
331 PUTVEC(R_ES
, R_BP
, ivec
[0x43]);
343 unknown_int4(0x10, 0x11, 0x30, R_BH
, REGS
);
348 unknown_int3(0x10, 0x11, R_AL
, REGS
);
352 case 0x12: /* Alternate function select */
356 case 0x10: /* Read EGA/VGA config */
357 R_BH
= NumColors
> 1 ? 0 : 1; /* Color */
358 R_BL
= 3; /* 256 K */
360 case 0x34: /* Cursor emulation */
370 unknown_int3(0x10, 0x12, R_BL
, REGS
);
374 case 0x13: /* write character string */
377 addr
= (char *)MAKEPTR(R_ES
, R_BP
);
378 switch (R_AL
& 0x03) {
380 tty_report(&saved_row
, &saved_col
);
381 tty_move(R_DH
, R_DL
);
382 for (i
= 0; i
< R_CX
; ++i
)
383 tty_write(*addr
++, R_BL
<< 8);
384 tty_move(saved_row
, saved_col
);
387 tty_move(R_DH
, R_DL
);
388 for (i
= 0; i
< R_CX
; ++i
)
389 tty_write(*addr
++, R_BL
<< 8);
392 tty_report(&saved_row
, &saved_col
);
393 tty_move(R_DH
, R_DL
);
394 for (i
= 0; i
< R_CX
; ++i
) {
395 tty_write(addr
[0], addr
[1]);
398 tty_move(saved_row
, saved_col
);
401 tty_move(R_DH
, R_DL
);
402 for (i
= 0; i
< R_CX
; ++i
) {
403 tty_write(addr
[0], addr
[1]);
412 R_AL
= 0x1a; /* I am VGA */
413 R_BL
= 8; /* Color VGA */
414 R_BH
= 0; /* No other card */
416 case 0x1b: /* Video Functionality/State information */
418 addr
= (char *)MAKEPTR(R_ES
, R_DI
);
419 memcpy(addr
, vga_status
, 64);
423 case 0x1c: /* Save/Restore video state */
424 debug(D_VIDEO
, "VGA: Save/restore video state\n");
427 case 0x30: /* Locate 3270PC configuration table */
431 case 0x4f: /* get VESA information */
432 R_AH
= 0x01; /* no VESA support */
436 case 0x00: /* HP-Vectra or Video7 installation check */
437 R_BX
= 0; /* nope, none of that */
440 unknown_int3(0x10, 0x6f, R_AL
, REGS
);
445 case 0xfe: /* Get video buffer */
447 case 0xfa: /* Interrogate mouse driver */
449 PUTPTR(R_ES
, R_BX
, (long)mouse_area
);
451 case 0xff: /* Update real screen from video buffer */
452 /* XXX - we should allow secondary buffer here and then
453 update it as the user requests. */
458 fatal("int10 function 0x%02x:%02x only available in X mode\n",
463 unknown_int3(0x10, R_AH
, R_AL
, REGS
);