iscontrol(8): Fix synopsis, sync usage() & improve markup
[dragonfly.git] / usr.bin / doscmd / int10.c
blobb6d1a2be582dd9618dbd407b8ee0a6b55550b95b
1 /*
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
7 * are met:
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
16 * Design, Inc.
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
28 * SUCH DAMAGE.
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 $
36 #include <unistd.h>
38 #include "doscmd.h"
39 #include "mouse.h"
40 #include "tty.h"
41 #include "video.h"
43 static int cursoremu = 1;
45 void
46 int10(regcontext_t *REGS)
48 char *addr;
49 int i, j;
50 int saved_row, saved_col;
53 * Any call to the video BIOS is enough to reset the poll
54 * count on the keyboard.
56 reset_poll();
58 switch (R_AH) {
59 case 0x00: /* Set display mode */
60 if (!xmode)
61 goto unsupported;
62 init_mode(R_AL);
63 break;
64 case 0x01: /* Define cursor */
66 int start, end;
68 start = R_CH;
69 end = R_CL;
70 if (cursoremu == 0)
71 goto out;
72 /* Cursor emulation */
73 if (start <= 3 && end <= 3)
74 goto out;
75 if (start + 2 >= end) {
76 /* underline cursor */
77 start = CharHeight - 3;
78 end = CharHeight - 2;
79 goto out;
81 if (start <= 2 || end < start) {
82 /* block cursor */
83 start = 0;
84 end = CharHeight - 2;
85 goto out;
87 if (start > CharHeight / 2) {
88 /* half block cursor */
89 start = CharHeight / 2;
90 end = 0;
92 out: CursStart = start;
93 CursEnd = end;
94 break;
96 case 0x02: /* Position cursor */
97 if (!xmode)
98 goto unsupported;
99 tty_move(R_DH, R_DL);
100 break;
101 case 0x03: /* Read cursor position */
102 if (!xmode)
103 goto unsupported;
104 tty_report(&i, &j);
105 R_DH = i;
106 R_DL = j;
107 R_CH = CursStart;
108 R_CL = CursEnd;
109 break;
110 case 0x05:
111 debug(D_VIDEO, "Select current display page %d\n", R_AL);
112 break;
113 case 0x06: /* initialize window/scroll text upward */
114 if (!xmode)
115 goto unsupported;
116 if (R_AL == 0) /* clear screen */
117 R_AL = DpyRows + 1;
118 tty_scroll(R_CH, R_CL,
119 R_DH, R_DL,
120 R_AL, R_BH << 8);
121 break;
122 case 0x07: /* initialize window/scroll text downward */
123 if (!xmode)
124 goto unsupported;
125 if (R_AL == 0) /* clear screen */
126 R_AL = DpyRows + 1;
127 tty_rscroll(R_CH, R_CL,
128 R_DH, R_DL,
129 R_AL, R_BH << 8);
130 break;
131 case 0x08: /* read character/attribute */
132 if (!xmode)
133 goto unsupported;
134 i = tty_char(-1, -1);
135 R_AX = i;
136 break;
137 case 0x09: /* write character/attribute */
138 if (!xmode)
139 goto unsupported;
140 tty_rwrite(R_CX, R_AL, R_BL << 8);
141 break;
142 case 0x0a: /* write character */
143 if (!xmode)
144 goto unsupported;
145 debug(D_HALF, "Int 10:0a: Write char: %02x\n", R_AL);
146 tty_rwrite(R_CX, R_AL, -1);
147 break;
148 case 0x0b: /* set border color */
149 if (!xmode)
150 goto unsupported;
151 video_setborder(R_BL);
152 break;
153 case 0x0c: /* write graphics pixel */
154 debug(D_VIDEO, "Write graphics pixel at %d, %d\n", R_CX, R_DX);
155 break;
156 case 0x0d: /* read graphics pixel */
157 debug(D_VIDEO, "Read graphics pixel at %d, %d\n", R_CX, R_DX);
158 break;
159 case 0x0e: /* write character */
160 tty_write(R_AL, -1);
161 break;
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 */
166 break;
167 case 0x10:
168 if (!xmode)
169 goto unsupported;
170 switch (R_AL) {
171 case 0x00: /* Set single palette register */
172 palette[R_BL] = R_BH;
173 update_pixels();
174 break;
175 case 0x01: /* Set overscan register */
176 VGA_ATC[ATC_OverscanColor] = R_BH;
177 break;
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;
183 update_pixels();
184 break;
185 case 0x03: /* Enable/Disable blinking mode */
186 video_blink((R_BL & 1) ? 1 : 0);
187 break;
188 case 0x07: /* Get individual palette register */
189 R_BH = palette[R_BL];
190 break;
191 case 0x08: /* Read overscan register */
192 R_BH = VGA_ATC[ATC_OverscanColor];
193 break;
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];
199 break;
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;
204 update_pixels();
205 break;
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++;
213 update_pixels();
214 break;
215 case 0x13: /* Select video DAC color page */
216 switch (R_BL) {
217 case 0:
218 VGA_ATC[ATC_ModeCtrl] |= (R_BH & 0x01) << 7;
219 break;
220 case 1:
221 VGA_ATC[ATC_ColorSelect] = R_BH & 0x0f;
222 break;
223 default:
224 debug(D_VIDEO, "INT 10 10:13 "
225 "Bad value for BL: 0x%02x\n", R_BL);
226 break;
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;
232 break;
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;
240 break;
241 case 0x18: /* Set PEL mask */
242 debug(D_HALF,
243 "INT 10 10:18 Set PEL mask (%02x)\n", R_BL);
244 break;
245 case 0x19: /* Read PEL mask */
246 debug(D_HALF, "INT 10 10:19 Read PEL mask\n");
247 break;
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];
251 break;
252 case 0x1b: /* Perform gray-scale summing */
253 debug(D_HALF, "Perform gray-scale summing\n");
254 break;
255 default:
256 unknown_int3(0x10, 0x10, R_AL, REGS);
257 break;
259 break;
260 case 0x11:
261 switch (R_AL) {
262 case 0x00: /* Text-mode chargen: load user-specified
263 patterns */
264 debug(D_VIDEO, "Tried to load user defined font.\n");
265 break;
266 case 0x01: /* Text-mode chargen: load ROM monochrome
267 patterns */
268 debug(D_VIDEO, "Tried to load 8x14 font.\n");
269 break;
270 case 0x02: /* Text-mode chargen: load ROM 8x8 double-dot
271 patterns */
272 debug(D_VIDEO, "Tried to load 8x8 font.\n");
273 break;
274 case 0x03: /* Text-mode chargen: set block specifier */
275 debug(D_VIDEO, "Tried to activate character set\n");
276 break;
277 case 0x04: /* Text-mode chargen: load ROM 8x16 character
278 set */
279 debug(D_VIDEO, "Tried to load 8x16 font.\n");
280 break;
281 case 0x10: /* Text-mode chargen: load and activate
282 user-specified patterns */
283 debug(D_VIDEO,
284 "Tried to load and activate user defined font\n");
285 break;
286 case 0x11: /* Text-mode chargen: load and activate ROM
287 monochrome patterns */
288 debug(D_VIDEO,
289 "Tried to load and activate 8x14 font.\n");
290 break;
291 case 0x12: /* Text-mode chargen: load and activate ROM
292 8x8 double-dot patterns */
293 debug(D_VIDEO,
294 "Tried to load and activate 8x8 font.\n");
295 break;
296 case 0x14: /* Text-mode chargen: load and activate ROM
297 8x16 character set */
298 debug(D_VIDEO,
299 "Tried to load and activate 8x16 font.\n");
300 break;
301 case 0x20: /* Graph-mode chargen: set user 8x8 graphics
302 characters */
303 debug(D_VIDEO, "Load second half of 8x8 char set\n");
304 break;
305 case 0x21: /* Graph-mode chargen: set user graphics
306 characters */
307 debug(D_VIDEO, "Install user defined char set\n");
308 break;
309 case 0x22: /* Graph-mode chargen: set ROM 8x14 graphics
310 chars */
311 debug(D_VIDEO, "Install 8x14 char set\n");
312 break;
313 case 0x23: /* Graph-mode chargen: set ROM 8x8 double-dot
314 chars */
315 debug(D_VIDEO, "Install 8x8 char set\n");
316 break;
317 case 0x24: /* Graph-mode chargen: load 8x16 graphics
318 chars */
319 debug(D_VIDEO, "Install 8x16 char set\n");
320 break;
321 case 0x30: /* Get font information */
322 debug(D_VIDEO,
323 "INT 10 11:30 Request font address %02x\n", R_BH);
324 R_CX = CharHeight;
325 R_DL = DpyRows;
326 switch(R_BH) {
327 case 0:
328 PUTVEC(R_ES, R_BP, ivec[0x1f]);
329 break;
330 case 1:
331 PUTVEC(R_ES, R_BP, ivec[0x43]);
332 break;
333 case 2:
334 case 3:
335 case 4:
336 case 5:
337 case 6:
338 case 7:
339 R_ES = 0;
340 R_BP = 0;
341 break;
342 default:
343 unknown_int4(0x10, 0x11, 0x30, R_BH, REGS);
344 break;
346 break;
347 default:
348 unknown_int3(0x10, 0x11, R_AL, REGS);
349 break;
351 break;
352 case 0x12: /* Alternate function select */
353 if (!xmode)
354 goto unsupported;
355 switch (R_BL) {
356 case 0x10: /* Read EGA/VGA config */
357 R_BH = NumColors > 1 ? 0 : 1; /* Color */
358 R_BL = 3; /* 256 K */
359 break;
360 case 0x34: /* Cursor emulation */
361 if (R_AL == 0)
362 cursoremu = 1;
363 else
364 cursoremu = 0;
365 R_AL = 0x12;
366 break;
367 default:
368 if (vflag)
369 dump_regs(REGS);
370 unknown_int3(0x10, 0x12, R_BL, REGS);
371 break;
373 break;
374 case 0x13: /* write character string */
375 if (!xmode)
376 goto unsupported;
377 addr = (char *)MAKEPTR(R_ES, R_BP);
378 switch (R_AL & 0x03) {
379 case 0:
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);
385 break;
386 case 1:
387 tty_move(R_DH, R_DL);
388 for (i = 0; i < R_CX; ++i)
389 tty_write(*addr++, R_BL << 8);
390 break;
391 case 2:
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]);
396 addr += 2;
398 tty_move(saved_row, saved_col);
399 break;
400 case 3:
401 tty_move(R_DH, R_DL);
402 for (i = 0; i < R_CX; ++i) {
403 tty_write(addr[0], addr[1]);
404 addr += 2;
406 break;
408 break;
409 case 0x1a:
410 if (!xmode)
411 goto unsupported;
412 R_AL = 0x1a; /* I am VGA */
413 R_BL = 8; /* Color VGA */
414 R_BH = 0; /* No other card */
415 break;
416 case 0x1b: /* Video Functionality/State information */
417 if (R_BX == 0) {
418 addr = (char *)MAKEPTR(R_ES, R_DI);
419 memcpy(addr, vga_status, 64);
420 R_AL = 0x1b;
422 break;
423 case 0x1c: /* Save/Restore video state */
424 debug(D_VIDEO, "VGA: Save/restore video state\n");
425 R_AL = 0;
426 break;
427 case 0x30: /* Locate 3270PC configuration table */
428 R_CX = 0;
429 R_DX = 0;
430 break;
431 case 0x4f: /* get VESA information */
432 R_AH = 0x01; /* no VESA support */
433 break;
434 case 0x6f:
435 switch (R_AL) {
436 case 0x00: /* HP-Vectra or Video7 installation check */
437 R_BX = 0; /* nope, none of that */
438 break;
439 default:
440 unknown_int3(0x10, 0x6f, R_AL, REGS);
441 break;
443 break;
444 case 0xef:
445 case 0xfe: /* Get video buffer */
446 break;
447 case 0xfa: /* Interrogate mouse driver */
448 if (xmode)
449 PUTPTR(R_ES, R_BX, (long)mouse_area);
450 break;
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. */
454 break;
455 unsupported:
456 if (vflag)
457 dump_regs(REGS);
458 fatal("int10 function 0x%02x:%02x only available in X mode\n",
459 R_AH, R_AL);
460 default:
461 if (vflag)
462 dump_regs(REGS);
463 unknown_int3(0x10, R_AH, R_AL, REGS);
464 break;