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 tty.c,v 2.4 1996/04/08 22:03:27 prb Exp
37 #include <X11/Xutil.h>
38 #include <X11/keysym.h>
45 #include <sys/ioctl.h>
51 # include <sys/kbio.h>
54 # include "machine/pccons.h"
56 # include "/sys/i386/isa/pcconsioctl.h"
66 static struct termios save = { 0 };
67 static struct termios raw = { 0 };
70 #define vmem ((u_short *)0xB8000)
72 int flipdelete = 0; /* Flip meaning of delete and backspace */
73 extern int capture_fd;
74 static u_short break_code = 0x00;
75 static u_short scan_code = 0x00;
78 static Display *dpy = 0;
80 static XFontStruct *font;
81 static unsigned long black;
82 static unsigned long white;
83 static unsigned long pixels[16];
84 static char *color_names[16] = {
103 static int FW, FH, FD;
111 static int vattr = 0x0700;
113 static int width = 80;
114 static int height = 25;
115 static struct termios tty_cook, tty_raw;
117 typedef struct TextLine {
119 u_char max_length; /* Not used, but here for future use */
122 static TextLine *lines;
125 * 0040:0050 is a list of 16 bytes, 2 for each page, which contains
126 * the column and row of each page
128 #define row BIOSDATA[0x51]
129 #define col BIOSDATA[0x50]
135 int cp = row * width + col;
136 VREG[MVC_CurHigh] = cp >> 8;
137 VREG[MVC_CurLow] = cp & 0xff;
141 * 0040:0060 contains the start and end of the cursor
143 #define curs_end BIOSDATA[0x60]
144 #define curs_start BIOSDATA[0x61]
146 #define video_pate BISODATA[0x62]
148 #define IBMFONT "vga" /* font supplied */
152 void video_async_event();
157 unsigned char video_inb(int);
158 unsigned char inb_port60(int);
159 void video_outb(int, unsigned char);
160 void kbd_event(int fd, REGISTERS);
161 u_short read_raw_kbd(int fd, u_short *code);
165 #define K_NEXT *(u_short *)0x41a
166 #define K_FREE *(u_short *)0x41c
167 #define K_BUFSTARTP *(u_short *)0x480
168 #define K_BUFENDP *(u_short *)0x482
169 #define K_BUFSTART ((u_short *)(0x400 + *(u_short *)0x480))
170 #define K_BUFEND ((u_short *)(0x400 + *(u_short *)0x482))
171 #define K_BUF(i) *((u_short *)((u_char *)0x400 + (i)))
173 #define K1_STATUS BIOSDATA[0x17]
174 #define K1_RSHIFT 0x01
175 #define K1_LSHIFT 0x02
176 #define K1_SHIFT 0x03
179 #define K1_SLOCK 0x10 /* Active */
180 #define K1_NLOCK 0x20 /* Active */
181 #define K1_CLOCK 0x40 /* Active */
182 #define K1_INSERT 0x80 /* Active */
184 #define K2_STATUS BIOSDATA[0x18]
185 #define K2_LCTRL 0x01
187 #define K2_SYSREQ 0x04
188 #define K2_PAUSE 0x08
189 #define K2_SLOCK 0x10 /* Actually held down */
190 #define K2_NLOCK 0x20 /* Actually held down */
191 #define K2_CLOCK 0x40 /* Actually held down */
192 #define K2_INSERT 0x80 /* Actually held down */
194 #define K3_STATUS BIOSDATA[0x96]
195 #define K3_E1 0x01 /* Last code read was e1 */
196 #define K3_E2 0x02 /* Last code read was e2 */
197 #define K3_RCTRL 0x04
199 #define K3_ENHANCED 0x10
200 #define K3_FORCENLOCK 0x20
201 #define K3_TWOBYTE 0x40 /* last code was first of 2 */
202 #define K3_READID 0x80 /* read ID in progress */
204 #define K4_STATUS BIOSDATA[0x97]
205 #define K4_SLOCK_LED 0x01
206 #define K4_NLOCK_LED 0x02
207 #define K4_CLOCK_LED 0x04
208 #define K4_ACK 0x10 /* ACK recieved from keyboard */
209 #define K4_RESEND 0x20 /* RESEND recieved from keyboard */
210 #define K4_LED 0x40 /* LED update in progress */
211 #define K4_ERROR 0x80
213 struct VideoSavePointerTable {
214 u_short video_parameter_tabel[2];
215 u_short parameter_dynamic_save_area[2]; /* Not used */
216 u_short alphanumeric_character_set_override[2]; /* Not used */
217 u_short graphics_character_set_override[2]; /* Not used */
218 u_short secondary_save_pointer_table[2]; /* Not used */
222 struct SecondaryVideoSavePointerTable {
224 u_short display_combination_code_table[2];
225 u_short alphanumeric_character_set_override[2]; /* Not used */
226 u_short user_palette_profile_table[2]; /* Not used */
231 void KbdWrite(u_short code);
232 void KbdRepl(u_short code);
243 fprintf(stderr, "X Connection shutdown\n");
247 struct VideoSavePointerTable *vsp;
248 struct SecondaryVideoSavePointerTable *svsp;
253 console_denit(void *arg)
255 int fd = *(int *)arg;
258 if (ioctl(fd, KDSKBMODE, K_XLATE))
259 perror("KDSKBMODE/K_XLATE");
262 if (ioctl(fd, CONSOLE_X_MODE_OFF, 0))
263 perror("CONSOLE_X_MODE_OFF");
265 if (ioctl(fd, PCCONIOCCOOK, 0))
266 perror("PCCONIOCCOOK");
269 if (tcsetattr(fd, TCSANOW, &tty_cook))
274 _kbd_event(int fd, REGISTERS)
276 printf("_kbd_event: fd=%d\n", fd);
286 if ((fd = open("/dev/vga", 2)) < 0) {
290 addr = mmap((caddr_t)0xA0000, 5 * 64 * 1024,
291 PROT_EXEC | PROT_READ | PROT_WRITE,
292 MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
294 if (addr != (caddr_t)0xA0000) {
300 addr = mmap((caddr_t)0x100000 - 0x1000, 0x1000,
301 PROT_EXEC | PROT_READ | PROT_WRITE,
302 MAP_FILE | MAP_FIXED | MAP_INHERIT | MAP_SHARED,
304 if (addr != (caddr_t)(0x100000 - 0x1000)) {
310 if ((fd = open(_PATH_CONSOLE, 2)) < 0) {
311 perror(_PATH_CONSOLE);
315 fd = squirrel_fd(fd);
319 if (ioctl(fd, KDSKBMODE, K_RAW)) {
320 perror("KDSKBMODE/K_RAW");
325 if (ioctl(fd, CONSOLE_X_MODE_ON, 0)) {
326 perror("CONSOLE_X_MODE_ON");
330 if (ioctl(fd, PCCONIOCRAW, 0)) {
331 perror("PCCONIOCRAW");
337 call_on_quit(console_denit, &kbd_fd);
339 if (fcntl(fd, F_SETFL, O_NDELAY|O_ASYNC) < 0) {
343 if (tcgetattr(fd, &tty_cook)) {
349 if (tcsetattr(fd, TCSANOW, &tty_raw)) {
355 _RegisterIO(0, debug_event, 0, Failure);
356 _RegisterIO(fd, kbd_event, fd, Failure);
358 _RegisterIO(fd, _kbd_event, fd, Failure);
362 video_setborder(int color)
366 XSetWindowBackground(dpy, win, pixels[color & 0xf]);
371 video_blink(int mode)
382 if (blink && !show && (attr & 0x8000))
383 v.foreground = pixels[(attr >> 12) & 0x07];
385 v.foreground = pixels[(attr >> 8) & 0x0f];
387 v.background = pixels[(attr >> 12) & (blink ? 0x07 : 0x0f)];
389 if (v.foreground == v.background) {
390 v.foreground = pixels[15];
391 v.background = pixels[0];
394 XChangeGC(dpy, gc, GCForeground|GCBackground, &v);
399 video_update(REGISTERS)
407 static char buf[256];
409 int attr = vmem[0] & 0xff00;
413 kbd_event(kbd_fd, REGS);
419 lpt_poll(); /* Handle timeout on lpt code */
422 wakeup_poll(); /* Wake up anyone waiting on kbd poll */
428 for (r = 0; r < height; ++r) {
431 if (!lines[r].changed) {
432 if ((r == or || r == row) && (or != row || oc != col))
433 lines[r].changed = 1;
435 for (c = 0; c < width; ++c) {
436 if (lines[r].data[c] != vmem[r * width + c]) {
437 lines[r].changed = 1;
440 if (blink && lines[r].data[c] & 0x8000) {
441 lines[r].changed = 1;
448 if (!lines[r].changed)
452 lines[r].changed = 0;
453 memcpy(lines[r].data,
454 &vmem[r * width], sizeof(u_short) * width);
456 for (c = 0; c < width; ++c) {
457 int cv = vmem[r * width + c];
458 if ((cv & 0xff00) != attr) {
460 XDrawImageString(dpy, win, gc,
468 buf[c] = (cv & 0xff) ? cv & 0xff : ' ';
471 XDrawImageString(dpy, win, gc,
480 if (curs_start <= curs_end && curs_end <= FH &&
481 show && row < height && col < width) {
484 attr = vmem[row * width + col] & 0xff00;
485 v.foreground = pixels[(attr >> 8) & 0x0f] ^
486 pixels[(attr >> 12) & (blink ? 0x07 : 0x0f)];
490 v.foreground = pixels[7];
493 XChangeGC(dpy, cgc, GCForeground | GCFunction, &v);
494 start = curs_start * FH / 8;
495 end = curs_end * FH / 8;
496 XFillRectangle(dpy, win, cgc,
498 2 + row * FH + start + FD,
499 FW, end + 1 - start);
502 if (mouse_status.installed && mouse_status.show) {
503 c = mouse_status.x / mouse_status.hmickey;
504 r = mouse_status.y / mouse_status.vmickey;
506 lines[r].changed = 1;
507 attr = vmem[r * width + c] & 0xff00;
508 v.foreground = pixels[(attr >> 8) & 0x0f] ^
509 pixels[(attr >> 12) & 0x0f];
513 v.foreground = pixels[7];
516 XChangeGC(dpy, cgc, GCForeground | GCFunction, &v);
517 XFillRectangle(dpy, win, cgc,
528 *(u_long *)&BIOSDATA[0x6c] += 1; /* Timer ticks since midnight... */
529 while (*(u_long *)&BIOSDATA[0x6c] >= 24*60*6*182) {
530 *(u_long *)&BIOSDATA[0x6c] -= 24*60*6*182;
531 BIOSDATA[0x70]++; /* BIOSDATA[0x70] # times past mn */
537 static u_short Ascii2Scan[] = {
538 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
539 0x000e, 0x000f, 0xffff, 0xffff, 0xffff, 0x001c, 0xffff, 0xffff,
540 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
541 0xffff, 0xffff, 0xffff, 0x0001, 0xffff, 0xffff, 0xffff, 0xffff,
542 0x0039, 0x0102, 0x0128, 0x0104, 0x0105, 0x0106, 0x0108, 0x0028,
543 0x010a, 0x010b, 0x0109, 0x010d, 0x0033, 0x000c, 0x0034, 0x0035,
544 0x000b, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
545 0x0009, 0x000a, 0x0127, 0x0027, 0x0133, 0x000d, 0x0134, 0x0135,
546 0x0103, 0x011e, 0x0130, 0x012e, 0x0120, 0x0112, 0x0121, 0x0122,
547 0x0123, 0x0117, 0x0124, 0x0125, 0x0126, 0x0132, 0x0131, 0x0118,
548 0x0119, 0x0110, 0x0113, 0x011f, 0x0114, 0x0116, 0x012f, 0x0111,
549 0x012d, 0x0115, 0x012c, 0x001a, 0x002b, 0x001b, 0x0107, 0x010c,
550 0x0029, 0x001e, 0x0030, 0x002e, 0x0020, 0x0012, 0x0021, 0x0022,
551 0x0023, 0x0017, 0x0024, 0x0025, 0x0026, 0x0032, 0x0031, 0x0018,
552 0x0019, 0x0010, 0x0013, 0x001f, 0x0014, 0x0016, 0x002f, 0x0011,
553 0x002d, 0x0015, 0x002c, 0x011a, 0x012b, 0x011b, 0x0129, 0xffff,
562 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 0 */
563 { 0x011b, 0x011b, 0x011b, 0xffff }, /* key 1 - Escape key */
564 { 0x0231, 0x0221, 0xffff, 0x7800 }, /* key 2 - '1' */
565 { 0x0332, 0x0340, 0x0300, 0x7900 }, /* key 3 - '2' - special handling */
566 { 0x0433, 0x0423, 0xffff, 0x7a00 }, /* key 4 - '3' */
567 { 0x0534, 0x0524, 0xffff, 0x7b00 }, /* key 5 - '4' */
568 { 0x0635, 0x0625, 0xffff, 0x7c00 }, /* key 6 - '5' */
569 { 0x0736, 0x075e, 0x071e, 0x7d00 }, /* key 7 - '6' */
570 { 0x0837, 0x0826, 0xffff, 0x7e00 }, /* key 8 - '7' */
571 { 0x0938, 0x092a, 0xffff, 0x7f00 }, /* key 9 - '8' */
572 { 0x0a39, 0x0a28, 0xffff, 0x8000 }, /* key 10 - '9' */
573 { 0x0b30, 0x0b29, 0xffff, 0x8100 }, /* key 11 - '0' */
574 { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200 }, /* key 12 - '-' */
575 { 0x0d3d, 0x0d2b, 0xffff, 0x8300 }, /* key 13 - '=' */
576 { 0x0e08, 0x0e08, 0x0e7f, 0xffff }, /* key 14 - backspace */
577 { 0x0f09, 0x0f00, 0xffff, 0xffff }, /* key 15 - tab */
578 { 0x1071, 0x1051, 0x1011, 0x1000 }, /* key 16 - 'Q' */
579 { 0x1177, 0x1157, 0x1117, 0x1100 }, /* key 17 - 'W' */
580 { 0x1265, 0x1245, 0x1205, 0x1200 }, /* key 18 - 'E' */
581 { 0x1372, 0x1352, 0x1312, 0x1300 }, /* key 19 - 'R' */
582 { 0x1474, 0x1454, 0x1414, 0x1400 }, /* key 20 - 'T' */
583 { 0x1579, 0x1559, 0x1519, 0x1500 }, /* key 21 - 'Y' */
584 { 0x1675, 0x1655, 0x1615, 0x1600 }, /* key 22 - 'U' */
585 { 0x1769, 0x1749, 0x1709, 0x1700 }, /* key 23 - 'I' */
586 { 0x186f, 0x184f, 0x180f, 0x1800 }, /* key 24 - 'O' */
587 { 0x1970, 0x1950, 0x1910, 0x1900 }, /* key 25 - 'P' */
588 { 0x1a5b, 0x1a7b, 0x1a1b, 0xffff }, /* key 26 - '[' */
589 { 0x1b5d, 0x1b7d, 0x1b1d, 0xffff }, /* key 27 - ']' */
590 { 0x1c0d, 0x1c0d, 0x1c0a, 0xffff }, /* key 28 - CR */
591 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 29 - control */
592 { 0x1e61, 0x1e41, 0x1e01, 0x1e00 }, /* key 30 - 'A' */
593 { 0x1f73, 0x1f53, 0x1f13, 0x1f00 }, /* key 31 - 'S' */
594 { 0x2064, 0x2044, 0x2004, 0x2000 }, /* key 32 - 'D' */
595 { 0x2166, 0x2146, 0x2106, 0x2100 }, /* key 33 - 'F' */
596 { 0x2267, 0x2247, 0x2207, 0x2200 }, /* key 34 - 'G' */
597 { 0x2368, 0x2348, 0x2308, 0x2300 }, /* key 35 - 'H' */
598 { 0x246a, 0x244a, 0x240a, 0x2400 }, /* key 36 - 'J' */
599 { 0x256b, 0x254b, 0x250b, 0x2500 }, /* key 37 - 'K' */
600 { 0x266c, 0x264c, 0x260c, 0x2600 }, /* key 38 - 'L' */
601 { 0x273b, 0x273a, 0xffff, 0xffff }, /* key 39 - ';' */
602 { 0x2827, 0x2822, 0xffff, 0xffff }, /* key 40 - ''' */
603 { 0x2960, 0x297e, 0xffff, 0xffff }, /* key 41 - '`' */
604 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 42 - left shift */
605 { 0x2b5c, 0x2b7c, 0x2b1c, 0xffff }, /* key 43 - '' */
606 { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00 }, /* key 44 - 'Z' */
607 { 0x2d78, 0x2d58, 0x2d18, 0x2d00 }, /* key 45 - 'X' */
608 { 0x2e63, 0x2e43, 0x2e03, 0x2e00 }, /* key 46 - 'C' */
609 { 0x2f76, 0x2f56, 0x2f16, 0x2f00 }, /* key 47 - 'V' */
610 { 0x3062, 0x3042, 0x3002, 0x3000 }, /* key 48 - 'B' */
611 { 0x316e, 0x314e, 0x310e, 0x3100 }, /* key 49 - 'N' */
612 { 0x326d, 0x324d, 0x320d, 0x3200 }, /* key 50 - 'M' */
613 { 0x332c, 0x333c, 0xffff, 0xffff }, /* key 51 - ',' */
614 { 0x342e, 0x343e, 0xffff, 0xffff }, /* key 52 - '.' */
615 { 0x352f, 0x353f, 0xffff, 0xffff }, /* key 53 - '/' */
616 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 54 - right shift - */
617 { 0x372a, 0xffff, 0x3772, 0xffff }, /* key 55 - prt-scr - */
618 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 56 - Alt - */
619 { 0x3920, 0x3920, 0x3920, 0x3920 }, /* key 57 - space bar */
620 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 58 - caps-lock - */
621 { 0x3b00, 0x5400, 0x5e00, 0x6800 }, /* key 59 - F1 */
622 { 0x3c00, 0x5500, 0x5f00, 0x6900 }, /* key 60 - F2 */
623 { 0x3d00, 0x5600, 0x6000, 0x6a00 }, /* key 61 - F3 */
624 { 0x3e00, 0x5700, 0x6100, 0x6b00 }, /* key 62 - F4 */
625 { 0x3f00, 0x5800, 0x6200, 0x6c00 }, /* key 63 - F5 */
626 { 0x4000, 0x5900, 0x6300, 0x6d00 }, /* key 64 - F6 */
627 { 0x4100, 0x5a00, 0x6400, 0x6e00 }, /* key 65 - F7 */
628 { 0x4200, 0x5b00, 0x6500, 0x6f00 }, /* key 66 - F8 */
629 { 0x4300, 0x5c00, 0x6600, 0x7000 }, /* key 67 - F9 */
630 { 0x4400, 0x5d00, 0x6700, 0x7100 }, /* key 68 - F10 */
631 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 69 - num-lock - */
632 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 70 - scroll-lock - */
633 { 0x4700, 0x4737, 0x7700, 0xffff }, /* key 71 - home */
634 { 0x4800, 0x4838, 0xffff, 0xffff }, /* key 72 - cursor up */
635 { 0x4900, 0x4939, 0x8400, 0xffff }, /* key 73 - page up */
636 { 0x4a2d, 0x4a2d, 0xffff, 0xffff }, /* key 74 - minus sign */
637 { 0x4b00, 0x4b34, 0x7300, 0xffff }, /* key 75 - cursor left */
638 { 0xffff, 0x4c35, 0xffff, 0xffff }, /* key 76 - center key */
639 { 0x4d00, 0x4d36, 0x7400, 0xffff }, /* key 77 - cursor right */
640 { 0x4e2b, 0x4e2b, 0xffff, 0xffff }, /* key 78 - plus sign */
641 { 0x4f00, 0x4f31, 0x7500, 0xffff }, /* key 79 - end */
642 { 0x5000, 0x5032, 0xffff, 0xffff }, /* key 80 - cursor down */
643 { 0x5100, 0x5133, 0x7600, 0xffff }, /* key 81 - page down */
644 { 0x5200, 0x5230, 0xffff, 0xffff }, /* key 82 - insert */
645 { 0x5300, 0x532e, 0xffff, 0xffff }, /* key 83 - delete */
646 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 84 - sys key */
647 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 85 */
648 { 0xffff, 0xffff, 0xffff, 0xffff }, /* key 86 */
649 { 0x8500, 0x5787, 0x8900, 0x8b00 }, /* key 87 - F11 */
650 { 0x8600, 0x5888, 0x8a00, 0x8c00 }, /* key 88 - F12 */
654 debug_event(int fd, REGISTERS)
656 static char ibuf[1024];
657 static char icnt = 0;
658 static u_short ds = 0;
659 static u_short di = 0;
660 static u_short cnt = 16 * 8;
665 r = read(0, ibuf + icnt, sizeof(ibuf) - icnt);
672 while (ep = strchr(ibuf, '\n')) {
678 ac = ParseBuffer(ibuf, av = _av, 16);
681 if (!strcasecmp(av[0], "dump")) {
684 if (c = strchr(av[1], ':')) {
685 ds = strtol(av[1], 0, 16);
686 di = strtol(c+1, 0, 16);
688 di = strtol(av[1], 0, 16);
691 cnt = strtol(av[2], 0, 0);
692 cnt = (cnt + 0xf) & ~0xf;
697 for (r = 0; r < cnt; r += 0x10, di = (di + 0x10) & 0xffff) {
699 u_char *ap = (u_char *)(((u_long)ds << 4) + di);
701 printf("%04x:%04x:", ds, di);
702 for (i = 0; i < 8; ++i)
703 printf(" %02x", ap[i]);
705 for (i = 8; i < 16; ++i)
706 printf(" %02x", ap[i]);
708 for (i = 0; i < 8; ++i)
709 printf("%c",(ap[i] < ' ' || ap[i] > '~') ? '.' : ap[i]);
711 for (i = 8; i < 16; ++i)
712 printf("%c",(ap[i] < ' ' || ap[i] > '~') ? '.' : ap[i]);
715 } else if (!strcasecmp(av[0], "dis")) {
717 u_char *ap = (u_char *)(((u_long)ds << 4) + di);
721 if (c = strchr(av[1], ':')) {
722 ds = strtol(av[1], 0, 16);
723 di = strtol(c+1, 0, 16);
725 di = strtol(av[1], 0, 16);
728 cnt = strtol(av[2], 0, 0);
730 for (r = 0; r < cnt; ++r) {
732 int c = i386dis(ds, di, ap, buf, 0);
733 printf("%04x:%04x %s\n", ds, di, buf);
737 } else if (!strcasecmp(av[0], "regs")) {
739 } else if (!strcasecmp(av[0], "force")) {
744 if (*p >= ' ' && *p <= '~')
745 KbdWrite(ScanCodes[Ascii2Scan[*p] & 0xff].base);
749 KbdWrite(ScanCodes[28].base);
750 } else if (!strcasecmp(av[0], "bell")) {
756 fprintf(stderr, "%s: unknown command\n", av[0]);
760 if (ep < ibuf + icnt) {
782 kbd_event(int fd, REGISTERS)
786 printf("kbd_event: fd=%d\n", fd);
787 if ((break_code = read_raw_kbd(fd, &scan_code)) != 0xffff)
795 if (scan_code != 0xffff) {
800 kbd_event(kbd_fd, sc);
807 read_raw_kbd(int fd, u_short *code)
810 unsigned char oldled = K4_STATUS & 0x7;
814 if (read(fd, &c, 1) == 1) {
816 K3_STATUS |= K3_TWOBYTE;
820 case 29: /* Control */
821 K1_STATUS |= K1_CTRL;
822 if (K3_STATUS & K3_TWOBYTE)
823 K3_STATUS |= K3_RCTRL;
825 K2_STATUS |= K2_LCTRL;
827 case 29 | 0x80: /* Control */
828 K1_STATUS &= ~K1_CTRL;
829 if (K3_STATUS & K3_TWOBYTE)
830 K3_STATUS &= ~K3_RCTRL;
832 K2_STATUS &= ~K2_LCTRL;
835 case 42: /* left shift */
836 K1_STATUS |= K1_LSHIFT;
838 case 42 | 0x80: /* left shift */
839 K1_STATUS &= ~K1_LSHIFT;
842 case 54: /* right shift */
843 K1_STATUS |= K1_RSHIFT;
845 case 54 | 0x80: /* right shift */
846 K1_STATUS &= ~K1_RSHIFT;
851 if (K3_STATUS & K3_TWOBYTE)
852 K3_STATUS |= K3_RALT;
854 K2_STATUS |= K2_LALT;
856 case 56 | 0x80: /* Alt */
857 K1_STATUS &= ~K1_ALT;
858 if (K3_STATUS & K3_TWOBYTE)
859 K3_STATUS &= ~K3_RALT;
861 K2_STATUS &= ~K2_LALT;
864 case 58: /* caps-lock */
865 K1_STATUS ^= K1_CLOCK;
866 if (K1_STATUS & K1_CLOCK)
867 K4_STATUS |= K4_CLOCK_LED;
869 K4_STATUS &= ~K4_CLOCK_LED;
870 K2_STATUS |= K2_CLOCK;
872 case 58 | 0x80: /* caps-lock */
873 K2_STATUS &= ~K2_CLOCK;
876 case 69: /* num-lock */
877 K1_STATUS ^= K1_NLOCK;
878 if (K1_STATUS & K1_NLOCK)
879 K4_STATUS |= K4_NLOCK_LED;
881 K4_STATUS &= ~K4_NLOCK_LED;
882 K2_STATUS |= K2_NLOCK;
884 case 69 | 0x80: /* num-lock */
885 K2_STATUS &= ~K2_NLOCK;
888 case 70: /* scroll-lock */
889 K1_STATUS ^= K1_SLOCK;
890 if (K1_STATUS & K1_SLOCK)
891 K4_STATUS |= K4_SLOCK_LED;
893 K4_STATUS &= ~K4_SLOCK_LED;
894 K2_STATUS |= K2_SLOCK;
896 case 70 | 0x80: /* scroll-lock */
897 K2_STATUS &= ~K2_SLOCK;
900 case 82: /* insert */
901 K1_STATUS ^= K1_INSERT;
902 K2_STATUS |= K2_INSERT;
904 case 82 | 0x80: /* insert */
905 K2_STATUS &= ~K2_INSERT;
911 if ((K4_STATUS & 0x07) != oldled) {
912 oldled = K4_STATUS & 0x07;
913 ioctl (fd, PCCONIOCSETLED, &oldled);
917 if (c == 83 && (K1_STATUS & (K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL))
923 if (K1_STATUS & K1_ALT) {
924 scode = ScanCodes[c].alt;
925 } else if (K1_STATUS & K1_CTRL) {
926 scode = ScanCodes[c].ctrl;
927 } else if (K1_STATUS & K1_SHIFT) {
928 scode = ScanCodes[c].shift;
930 scode = ScanCodes[c].base;
931 if (K1_STATUS & K1_CLOCK) {
932 if (islower(scode & 0xff)) {
933 scode = (scode & 0xff00) | toupper(scode & 0xff);
936 if ((K1_STATUS & K1_NLOCK) && (K3_STATUS & K3_TWOBYTE) == 0) {
939 case 72: /* cursor up */
940 case 73: /* page up */
941 case 75: /* cursor left */
942 case 76: /* center key */
943 case 77: /* cursor right */
945 case 80: /* cursor down */
946 case 81: /* page down */
947 case 82: /* insert */
948 case 83: /* delete */
949 scode = ScanCodes[c].shift;
956 K3_STATUS &= ~K3_TWOBYTE;
957 if ((K1_STATUS&(K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) {
960 kill(getpid(), SIGALRM); /* force redraw */
961 printf("FORCED REDRAW\n");
966 resettrace(&saved_sigframe->sf_uc.uc_mcontext);
979 video_async_event(int fd, regcontext_t *REGS)
988 static struct timeval tv = { 0 };
991 * Handle any events just sitting around...
994 while (QLength(dpy) > 0) {
995 XNextEvent(dpy, &ev);
996 int09 |= video_event(&ev);
1002 x = select(FD_SETSIZE, &fdset, 0, 0, &tv);
1007 * Errno might be wrong, so we just select again.
1008 * This could cause a problem is something really
1009 * was wrong with select....
1019 if (FD_ISSET(fd, &fdset)) {
1021 XNextEvent(dpy, &ev);
1022 int09 |= video_event(&ev);
1023 } while (QLength(dpy));
1032 kbd_async_event(int fd, REGISTERS)
1036 unsigned char oldled = K4_STATUS & 0x7;
1038 while (read(fd, &c, 1) == 1) {
1040 case 29: /* Control */
1041 K1_STATUS |= K1_CTRL;
1042 K2_STATUS |= K2_LCTRL;
1044 case 29 | 0x80: /* Control */
1045 K1_STATUS &= ~K1_CTRL;
1046 K2_STATUS &= ~K2_LCTRL;
1049 case 42: /* left shift */
1050 K1_STATUS |= K1_LSHIFT;
1052 case 42 | 0x80: /* left shift */
1053 K1_STATUS &= ~K1_LSHIFT;
1056 case 54: /* right shift */
1057 K1_STATUS |= K1_RSHIFT;
1059 case 54 | 0x80: /* right shift */
1060 K1_STATUS &= ~K1_RSHIFT;
1064 K1_STATUS |= K1_ALT;
1065 K2_STATUS |= K2_LALT;
1067 case 56 | 0x80: /* Alt */
1068 K1_STATUS &= ~K1_ALT;
1069 K2_STATUS &= ~K2_LALT;
1072 case 58: /* caps-lock */
1073 if (K1_STATUS ^= K1_CLOCK)
1074 K4_STATUS &= ~K4_CLOCK_LED;
1076 K4_STATUS |= K4_CLOCK_LED;
1077 K2_STATUS |= K2_CLOCK;
1079 case 58 | 0x80: /* caps-lock */
1080 K2_STATUS &= ~K2_CLOCK;
1083 case 69: /* num-lock */
1084 if (K1_STATUS ^= K1_CLOCK)
1085 K4_STATUS &= ~K4_NLOCK_LED;
1087 K4_STATUS |= K4_NLOCK_LED;
1088 K2_STATUS |= K2_NLOCK;
1090 case 69 | 0x80: /* num-lock */
1091 K2_STATUS &= ~K2_NLOCK;
1094 case 70: /* scroll-lock */
1095 if (K1_STATUS ^= K1_SLOCK)
1096 K4_STATUS &= ~K4_SLOCK_LED;
1098 K4_STATUS |= K4_SLOCK_LED;
1099 K2_STATUS |= K2_SLOCK;
1101 case 70 | 0x80: /* scroll-lock */
1102 K2_STATUS &= ~K2_SLOCK;
1105 case 82: /* insert */
1106 K1_STATUS ^= K1_INSERT;
1107 K2_STATUS |= K2_INSERT;
1109 case 82 | 0x80: /* insert */
1110 K2_STATUS &= ~K2_INSERT;
1118 if ((K4_STATUS & 0x07) != oldled) {
1119 oldled = K4_STATUS & 0x07;
1120 ioctl (fd, PCCONIOCSETLED, &oldled);
1127 video_event(XEvent *ev)
1130 case MotionNotify: {
1131 XMotionEvent *me = (XMotionEvent *)ev;
1135 mouse_status.x = (me->x < mouse_status.range.x)
1136 ? mouse_status.range.x
1137 : (me->x > mouse_status.range.w)
1138 ? mouse_status.range.w : me->x;
1139 mouse_status.y = (me->y < mouse_status.range.y)
1140 ? mouse_status.range.y
1141 : (me->y > mouse_status.range.h)
1142 ? mouse_status.range.h : me->y;
1145 case ButtonRelease: {
1146 XButtonEvent *be = (XButtonEvent *)ev;
1151 mouse_status.ups[be->button]++;
1153 mouse_status.x = (be->x < mouse_status.range.x)
1154 ? mouse_status.range.x
1155 : (be->x > mouse_status.range.w)
1156 ? mouse_status.range.w : be->x;
1157 mouse_status.y = (be->y < mouse_status.range.y)
1158 ? mouse_status.range.y
1159 : (be->y > mouse_status.range.h)
1160 ? mouse_status.range.h : be->y;
1164 XButtonEvent *be = (XButtonEvent *)ev;
1169 mouse_status.downs[be->button]++;
1171 mouse_status.x = (be->x < mouse_status.range.x)
1172 ? mouse_status.range.x
1173 : (be->x > mouse_status.range.w)
1174 ? mouse_status.range.w : be->x;
1175 mouse_status.y = (be->y < mouse_status.range.y)
1176 ? mouse_status.range.y
1177 : (be->y > mouse_status.range.h)
1178 ? mouse_status.range.h : be->y;
1180 if ((K1_STATUS & (K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) {
1187 case GraphicsExpose:
1190 for (r = 0; r < height; ++r)
1191 lines[r].changed = 1;
1195 static char buf[128];
1201 if (!(ev->xkey.state & ShiftMask)) {
1202 K1_STATUS &= ~K1_LSHIFT;
1203 K1_STATUS &= ~K1_RSHIFT;
1205 if (!(ev->xkey.state & ControlMask)) {
1206 K1_STATUS &= ~K1_CTRL;
1207 K2_STATUS &= ~K2_LCTRL;
1208 K3_STATUS &= ~K3_RCTRL;
1210 if (!(ev->xkey.state & Mod1Mask)) {
1211 K1_STATUS &= ~K1_ALT;
1212 K2_STATUS &= ~K2_LALT;
1213 K3_STATUS &= ~K3_RALT;
1215 if (!(ev->xkey.state & LockMask)) {
1216 K2_STATUS &= ~K2_CLOCK;
1219 XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0);
1222 K1_STATUS &= ~K1_LSHIFT;
1225 K1_STATUS &= ~K1_RSHIFT;
1228 K1_STATUS &= ~K1_CTRL;
1229 K2_STATUS &= ~K2_LCTRL;
1232 K1_STATUS &= ~K1_CTRL;
1233 K3_STATUS &= ~K3_RCTRL;
1236 K1_STATUS &= ~K1_ALT;
1237 K2_STATUS &= ~K2_LALT;
1240 K1_STATUS &= ~K1_ALT;
1241 K3_STATUS &= ~K3_RALT;
1243 case XK_Scroll_Lock:
1244 K2_STATUS &= ~K2_SLOCK;
1247 K2_STATUS &= ~K2_NLOCK;
1250 K2_STATUS &= ~K2_CLOCK;
1253 K2_STATUS &= ~K2_INSERT;
1259 static char buf[128];
1263 u_short scan = 0xffff;
1265 if (!(ev->xkey.state & ShiftMask)) {
1266 K1_STATUS &= ~K1_LSHIFT;
1267 K1_STATUS &= ~K1_RSHIFT;
1269 if (!(ev->xkey.state & ControlMask)) {
1270 K1_STATUS &= ~K1_CTRL;
1271 K2_STATUS &= ~K2_LCTRL;
1272 K3_STATUS &= ~K3_RCTRL;
1274 if (!(ev->xkey.state & Mod1Mask)) {
1275 K1_STATUS &= ~K1_ALT;
1276 K2_STATUS &= ~K2_LALT;
1277 K3_STATUS &= ~K3_RALT;
1279 if (!(ev->xkey.state & LockMask)) {
1280 K2_STATUS &= ~K2_CLOCK;
1283 n = XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0);
1287 K1_STATUS |= K1_LSHIFT;
1290 K1_STATUS |= K1_RSHIFT;
1293 K1_STATUS |= K1_CTRL;
1294 K2_STATUS |= K2_LCTRL;
1297 K1_STATUS |= K1_CTRL;
1298 K3_STATUS |= K3_RCTRL;
1301 K1_STATUS |= K1_ALT;
1302 K2_STATUS |= K2_LALT;
1305 K1_STATUS |= K1_ALT;
1306 K3_STATUS |= K3_RALT;
1308 case XK_Scroll_Lock:
1309 K1_STATUS ^= K1_SLOCK;
1310 K2_STATUS |= K2_SLOCK;
1313 K1_STATUS ^= K1_NLOCK;
1314 K2_STATUS |= K2_NLOCK;
1317 K1_STATUS ^= K1_CLOCK;
1318 K2_STATUS |= K2_CLOCK;
1322 K1_STATUS ^= K1_INSERT;
1323 K2_STATUS |= K2_INSERT;
1332 case XK_ISO_Left_Tab:
1355 scan = ks - XK_F1 + 59;
1376 case XK_KP_Subtract:
1420 /* case XK_Insert: This is above */
1431 scan = flipdelete ? 14 : 83;
1435 scan = flipdelete ? 83 : 14;
1447 scan = Ascii2Scan['/'];
1450 case XK_KP_Multiply:
1451 scan = Ascii2Scan['*'];
1455 if ((K1_STATUS&(K1_ALT|K1_CTRL)) == (K1_ALT|K1_CTRL)) {
1456 if (ks == 'T' || ks == 't') {
1459 resettrace(&saved_sigframe->
1463 if (ks == 'R' || ks == 'r') {
1464 kill(getpid(), SIGALRM); /* redraw */
1468 if (ks < ' ' || ks > '~')
1470 scan = Ascii2Scan[ks];
1475 if ((scan & ~0x100) > 88) {
1480 if ((K1_STATUS & K1_SHIFT) || (scan & 0x100)) {
1481 scan = ScanCodes[scan & 0xff].shift;
1482 } else if (K1_STATUS & K1_CTRL) {
1483 scan = ScanCodes[scan & 0xff].ctrl;
1484 } else if (K1_STATUS & K1_ALT) {
1485 scan = ScanCodes[scan & 0xff].alt;
1487 scan = ScanCodes[scan & 0xff].base;
1491 if (scan != 0xffff) {
1492 break_code = scan >> 8;
1504 #define R03D4 BIOSDATA[0x65]
1505 static u_char R03BA = 0;
1506 static u_char R03DA = 0;
1513 R03DA += 1; /* Just cylce throught the values */
1514 return(R03DA &= 0x0f);
1515 case 0x03c2: /* Misc */
1516 case 0x03cc: /* Misc */
1520 return(VREG[R03D4]);
1527 video_outb(int port, unsigned char value)
1534 if ((value & 0x1) == 0) /* Trying to request monochrome */
1538 if (value & 0x22) /* Trying to select graphics */
1542 R03D4 = value & 0x1f;
1547 VREG[R03D4] = value;
1550 cp = row * width + col;
1552 cp |= (value << 8) & 0xff00;
1557 cp = row * width + col;
1569 tty_move(int r, int c)
1577 tty_report(int *r, int *c)
1586 K_NEXT = K_FREE = K_BUFSTARTP;
1594 if (row > (height - 1))
1596 else if (++row >= height) {
1598 memcpy(vmem, &vmem[width], 2 * width * (height - 1));
1599 for (i = 0; i < width; ++i)
1600 vmem[(height - 1) * width + i] = vattr | ' ';
1606 tty_write(int c, int attr)
1608 if (attr == TTYF_REDIRECT) {
1616 if (capture_fd >= 0) {
1618 write(capture_fd, &cc, 1);
1628 write(1, "\007", 1);
1631 if (row > (height - 1) || col > width)
1635 vmem[row * width + col] &= 0xff00;
1638 if (row > (height - 1))
1640 col = (col + 8) & ~0x07;
1657 if (row > (height - 1))
1660 vmem[row * width + col] = attr & 0xff00;
1662 vmem[row * width + col] &= 0xff00;
1663 vmem[row * width + col++] |= c;
1670 tty_rwrite(int n, int c, int attr)
1682 if (row > (height - 1))
1685 vmem[row * width + col] = attr & 0xff00;
1687 vmem[row * width + col] &= 0xff00;
1688 vmem[row * width + col++] |= c;
1700 sigprocmask(0, 0, &set);
1701 sigdelset(&set, SIGIO);
1702 sigdelset(&set, SIGALRM);
1706 static int nextchar = 0;
1709 tty_read(REGISTERS, int flag)
1718 if ((flag & TTYF_REDIRECT) && redirect0) {
1720 if (read(0, &c, 1) != 1)
1728 if (flag & TTYF_BLOCK) {
1737 if ((r & 0xff) == 0)
1740 if (flag & TTYF_CTRL) {
1743 * XXX - Not quite sure where we should return, maybe not
1744 * all the way to the user, but...
1746 if (ivec[0x23] && (ivec[0x23] >> 16) != 0xF000) {
1747 fake_int(REGS, 0x23);
1753 if (flag & TTYF_ECHO) {
1754 if ((flag & TTYF_ECHONL) && (r == '\n' || r == '\r')) {
1755 tty_write('\r', -1);
1756 tty_write('\n', -1);
1764 tty_peek(REGISTERS, int flag)
1769 return(nextchar & 0xff);
1772 if (flag & TTYF_POLL) {
1776 } else if (flag & TTYF_BLOCK) {
1783 if ((c & 0xff) == 3) {
1785 * XXX - Not quite sure where we should return, maybe not
1786 * all the way to the user, but...
1788 if (ivec[0x23] && (ivec[0x23] >> 16) != 0xF000) {
1789 fake_int(REGS, 0x23);
1806 if (K2_STATUS & K2_SYSREQ)
1808 if (K2_STATUS & K2_CLOCK)
1810 if (K2_STATUS & K2_NLOCK)
1812 if (K2_STATUS & K2_SLOCK)
1814 if (K3_STATUS & K3_RALT)
1816 if (K3_STATUS & K3_RCTRL)
1818 if (K2_STATUS & K2_LALT)
1820 if (K2_STATUS & K2_LCTRL)
1826 inrange(int a, int n, int x)
1828 return(a < n ? n : a > x ? x : a);
1832 tty_scroll(int sr, int sc, int er, int ec, int n, int attr)
1836 sr = inrange(sr, 0, height);
1837 er = inrange(er, 0, height);
1838 sc = inrange(sc, 0, width);
1839 ec = inrange(ec, 0, width);
1840 if (sr > er || sc > ec)
1848 if (n > 0 && n < er - sr) {
1849 for (j = sr; j < er - n; ) {
1850 memcpy(&vmem[j * width + sc],
1851 &vmem[(j + n) * width + sc],
1852 sizeof(vmem[0]) * (ec - sc));
1857 for (j = er - n; j < er; ) {
1858 for (i = sc; i < ec; ++i)
1859 vmem[j * width + i] = attr;
1865 tty_rscroll(int sr, int sc, int er, int ec, int n, int attr)
1869 sr = inrange(sr, 0, height);
1870 er = inrange(er, 0, height);
1871 sc = inrange(sc, 0, width);
1872 ec = inrange(ec, 0, width);
1873 if (sr > er || sc > ec)
1881 if (n > 0 && n < er - sr) {
1882 for (j = er; j > sr + n; ) {
1884 memcpy(&vmem[j * width + sc],
1885 &vmem[(j - n) * width + sc],
1886 sizeof(vmem[0]) * (ec - sc));
1890 for (j = sr + n; j > sr; ) {
1892 for (i = sc; i < ec; ++i)
1893 vmem[j * width + i] = attr;
1898 tty_char(int r, int c)
1904 r = inrange(r, 0, height);
1905 c = inrange(c, 0, width);
1906 return(vmem[r * width + c]);
1912 return(K_NEXT == K_FREE);
1916 KbdWrite(u_short code)
1921 if (kf == K_BUFENDP)
1930 K_BUF(K_FREE) = code;
1935 KbdRepl(u_short code)
1937 K_BUF(K_NEXT) = code;
1945 K_NEXT = K_NEXT + 2;
1946 if (K_NEXT == K_BUFENDP)
1947 K_NEXT = K_BUFSTARTP;
1955 return(K_BUF(K_NEXT));
1958 void int10(REGISTERS);
1973 VREG = (u_char *)malloc(32);
1976 * Define all known I/O port handlers
1978 define_input_port_handler(0x60, inb_port60);
1981 define_input_port_handler(CGA_Status, video_inb);
1982 define_input_port_handler(0x03c2, video_inb);
1983 define_input_port_handler(0x03cc, video_inb);
1984 define_input_port_handler(CVC_Data, video_inb);
1985 define_output_port_handler(CGA_Control, video_outb);
1986 define_output_port_handler(0x03c2, video_outb);
1987 define_output_port_handler(0x03cc, video_outb);
1988 define_output_port_handler(CVC_Address, video_outb);
1989 define_output_port_handler(CVC_Data, video_outb);
1992 redirect0 = isatty(0) == 0 || !xmode ;
1993 redirect1 = isatty(1) == 0 || !xmode ;
1994 redirect2 = isatty(2) == 0 || !xmode ;
1996 K_BUFSTARTP = 0x1e; /* Start of keyboard buffer */
1997 K_BUFENDP = 0x3e; /* End of keyboard buffer */
1998 K_NEXT = K_FREE = K_BUFSTARTP;
2000 vec = insert_hardint_trampoline();
2002 register_callback(vec, int09, "int 09");
2005 * Initialize video memory with black background, white foreground
2007 for (i = 0; i < height * width; ++i)
2014 if (!(lines = (TextLine *)malloc(sizeof(TextLine) * height))) {
2015 fprintf(stderr, "Could not allocate data structure for text lines\n");
2018 for (i = 0; i < height; ++i) {
2019 lines[i].max_length = width;
2020 if (!(lines[i].data = (u_short *)malloc(width * sizeof(u_short)))) {
2022 "Could not allocate data structure for text lines\n");
2025 lines[i].changed = 1;
2031 * Arg... I can no longer change X's fd out from under it.
2032 * Open up all the available fd's, leave 3 behind for X
2033 * to play with, open X and then release all the other fds
2035 int nfds = sysconf(_SC_OPEN_MAX);
2036 int *fds = malloc(sizeof(int) * nfds);
2039 for (i = 0; i < nfds && (i == 0 || fds[i-1] < 63); ++i)
2040 if ((fds[i] = open(_PATH_DEVNULL, 0)) < 0)
2043 * Leave 3 fds behind for X to play with
2045 if (i > 0) close(fds[--i]);
2046 if (i > 0) close(fds[--i]);
2047 if (i > 0) close(fds[--i]);
2049 dpy = XOpenDisplay(NULL);
2056 fprintf(stderr, "Could not open display ``%s''\n",
2057 XDisplayName(NULL));
2060 xfd = ConnectionNumber(dpy);
2062 _RegisterIO(xfd, video_async_event, xfd, Failure);
2063 if (debug_flags & D_DEBUGIN)
2064 _RegisterIO(0, debug_event, 0, Failure);
2067 pixels[0] = BlackPixel(dpy, DefaultScreen(dpy));
2068 pixels[15] = WhitePixel(dpy, DefaultScreen(dpy));
2069 for (i = 0; i < 15; ++i) {
2070 if (XAllocNamedColor(dpy,
2071 DefaultColormap(dpy, DefaultScreen(dpy)),
2072 color_names[i], &ccd, &rgb)) {
2073 pixels[i] = ccd.pixel;
2075 pixels[i] = pixels[0];
2077 pixels[i] = pixels[15];
2083 font = XLoadQueryFont(dpy, xfont);
2086 font = XLoadQueryFont(dpy, IBMFONT);
2089 fprintf(stderr, "Could not open font ``%s''\n", xfont);
2093 FW = font->max_bounds.width;
2094 FH = font->max_bounds.ascent + font->max_bounds.descent;
2095 FD = font->max_bounds.descent;
2100 sh.width = FW * width + 4;
2101 sh.height = FH * height + 4;
2106 sh.min_width = sh.max_width = sh.width;
2107 sh.min_height = sh.max_height = sh.height;
2109 sh.flags = USSize | PMinSize | PMaxSize | PSize;
2111 win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
2112 sh.width, sh.height, 2, black, black);
2114 fprintf(stderr, "Could not create window\n");
2118 gcv.foreground = white;
2119 gcv.background = black;
2120 gcv.font = font->fid;
2122 mask = GCForeground | GCBackground | GCFont;
2124 gc = XCreateGC(dpy, win, mask, &gcv);
2128 gcv.function = GXxor;
2129 cgc = XCreateGC(dpy, win, GCForeground|GCBackground|GCFunction, &gcv);
2131 XSetNormalHints(dpy, win, &sh);
2133 XSelectInput(dpy, win, ExposureMask | ButtonPressMask
2134 | ButtonReleaseMask | PointerMotionMask );
2136 XSelectInput(dpy, win, KeyReleaseMask | KeyPressMask |
2137 ExposureMask | ButtonPressMask
2138 | ButtonReleaseMask | PointerMotionMask );
2141 XStoreName(dpy, win, "DOS");
2142 XMapWindow(dpy, win);
2159 * Put the Video Save Pointer table @ C000:0000
2160 * Put the Secondary Video Save Pointer table @ C000:0020
2161 * Put the Display Combination code table @ C000:0040
2162 * Put the Video Parameter table @ C000:1000 - C000:2FFF
2163 * Put the default Font @ C000:3000 - C000:3FFF
2166 *(u_long *)&BIOSDATA[0xA8] = 0xC0000000; /* 0040:00A8 points to us */
2168 vsp = (struct VideoSavePointerTable *)0xC0000L;
2169 memset(vsp, 0, sizeof(struct VideoSavePointerTable));
2170 svsp = (struct SecondaryVideoSavePointerTable *)0xC0020L;
2172 vsp->video_parameter_tabel[0] = 0x1000;
2173 vsp->video_parameter_tabel[1] = 0xC000;
2175 vsp->secondary_save_pointer_table[0] = 0x0020;
2176 vsp->secondary_save_pointer_table[1] = 0xC000;
2178 svsp->display_combination_code_table[0] = 0x0040;
2179 svsp->display_combination_code_table[1] = 0xC000;
2181 p = (u_char *)0xC0040;
2182 *p++ = 2; /* Only support 2 combinations currently */
2183 *p++ = 1; /* Version # */
2184 *p++ = 8; /* We wont use more than type 8 */
2185 *p++ = 0; /* Resereved */
2186 *p++ = 0; *p++ = 0; /* No Display No Display */
2187 *p++ = 0; *p++ = 8; /* No Display VGA Color */
2189 memcpy((void *)0xC1000, videoparams, sizeof(videoparams));
2191 ivec[0x1d] = 0xC0001000L; /* Video Parameter Table */
2192 ivec[0x1e] = 0xC0003000L;
2193 ivec[0x42] = ivec[0x10]; /* Copy of video interrupt */
2194 memcpy((void *)0xC3000L, ascii_font, sizeof(ascii_font));
2196 BIOSDATA[0x49] = 3; /* Video Mode */
2197 *(u_short *)&BIOSDATA[0x4a] = 80; /* Columns on Screen */
2198 *(u_short *)&BIOSDATA[0x4c] = 0; /* Page */
2199 *(u_short *)&BIOSDATA[0x4e] = 0; /* Offset into video memory */
2200 *(u_short *)&BIOSDATA[0x63] = 0x03d4; /* controller base reg */
2201 BIOSDATA[0x84] = 24; /* Rows on screen */
2202 *(u_short *)&BIOSDATA[0x85] = 16; /* font height */
2203 BIOSDATA[0x87] = 0; /* video ram etc. */
2204 BIOSDATA[0x88] = 0xf9; /* video switches */
2205 BIOSDATA[0x89] = 0x11; /* video stats */
2206 BIOSDATA[0x8a] = 1; /* Index into DCC table */
2207 BIOSDATA[0x96] = 0x10;
2213 vec = insert_softint_trampoline();
2215 register_callback(vec, int10, "int 10");