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);