home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / graph.d < prev    next >
Encoding:
Text File  |  1994-12-07  |  143.7 KB  |  3,802 lines

  1. # Pixel-Graphik fⁿr CLISP
  2. # Bruno Haible 7.12.1994
  3.  
  4. #include "lispbibl.c"
  5. #include "arilev0.c" # wegen dreisatz
  6.  
  7.  
  8. /*
  9.  
  10. Graphics primitives in CLISP
  11. ============================
  12.  
  13. In CLISP 1994-01-07 or newer,
  14. * DOS version,
  15. * Linux version, installed setuid root,
  16. there are some pixel graphics primitives in the SYSTEM package.
  17. They operate on a VGA card.
  18.  
  19. Similar pixel graphics primitives can be used in the
  20. * Unix version running under X11
  21. by use of the small XTERM package available on
  22. ma2s2.mathematik.uni-karlsruhe.de.
  23.  
  24. This is the description of the PC/VGA graphics primitives:
  25.  
  26. (SYSTEM::GRAPH-INIT [width [height [colors]]])
  27. initializes the graphics system. The width, height parameters are hints for
  28. the size of the desired graphics screen (positive integers). The colors
  29. parameter is a hint for the number of colors. The actual width, height
  30. is implementation dependent, currently up to 640x480 on VGA cards and up to
  31. 1024x768 on ET4000 SVGA cards.
  32. Returns an alist ((color-value color-keyword) ...) which lists the available
  33. colours and their numerical equivalents.
  34.  
  35. (SYSTEM::GRAPH-SHOW)
  36. switches the graphics hardware so that the graphics screen is visible. The
  37. text screen is activated on any text output.
  38.  
  39. (SYSTEM::GRAPH-CLEAR [color])
  40. fills the entire graphics screen with a single color.
  41.  
  42. (SYSTEM::GRAPH-DIMS)
  43. returns two values: the actual width and the actual height of the graphics
  44. screen (in pixels).
  45.  
  46. If (SYSTEM::GRAPH-DIMS) returns the values w and h, then valid screen
  47. coordinates are pairs (x,y) with 0 <= x < w and 0 <= y < h. x=0 denotes the
  48. left edge, y=0 the top edge.
  49.  
  50. (SYSTEM::GRAPH-DOT x y)
  51. returns the colour of the pixel (x,y).
  52. (SYSTEM::GRAPH-DOT x y color)
  53. sets the colour of the pixel (x,y) to color.
  54.  
  55. (SYSTEM::GRAPH-BOX x1 y1 x2 y2 color)
  56. draws a box (= filled rectangle) in colour color, the vertices being the pixels
  57.         (x1,y1)   (x2,y1)
  58.         (x1,y2)   (x2,y2)
  59.  
  60. (SYSTEM::GRAPH-LINE x1 y1 x2 y2 color)
  61. Draws a line in colour color from pixel (x1,y1) to pixel (x2,y2).
  62.  
  63. (SYSTEM::GRAPH-TEXT x y dir string color)
  64. Paints the text contained in string, starting at (x,y), in colour color,
  65. and returns as values the end coordinates (x,y). dir is the direction:
  66. 0 goes to the right, 90 vertically up, 180 to the left, 270 vertically down.
  67.  
  68. This specification is subject to change.
  69.  
  70. */
  71.  
  72.  
  73. #ifdef GRAPHICS
  74.  
  75.  
  76. # Low-Level-Funktionen der Pixel-Grafik:
  77. # gr_init(width,height,colors);  erzeugt einen Grafik-Bildschirm mit
  78. #                                (andeutungsweise) gegebener Gr÷▀e.
  79. # gr_show();                     zeigt den Grafik-Bildschirm an.
  80. # gr_colors()                    liefert einen Array von benannten Farben.
  81. # gr_clear(color);               l÷scht den gesamten Grafik-Bildschirm.
  82. # gr_xdim                        Breite des Grafik-Bildschirms in Pixeln.
  83. # gr_ydim                        H÷he des Grafik-Bildschirms in Pixeln.
  84. # gr_get(x,y)                    liefert die Farbe des Punktes (x,y)
  85. # gr_dot(color,x,y);             zeichnet einen Punkt (x,y)
  86. # gr_box(color,x1,y1,x2,y2);     zeichnet ein Rechteck [x1,x2] x [y1,y2]
  87. # gr_line(color,x1,y1,x2,y2);    zeichnet eine Linie von (x1,y1) bis (x2,y2)
  88. # gr_text(color,&x,&y,dir,charptr,count);  zeichnet einen String ab (x,y)
  89.  
  90. struct named_color
  91. {
  92.     int color;
  93.     char* name;
  94. };
  95.  
  96.  
  97. # Hilfsfunktionen fⁿrs Clipping:
  98.  
  99. # dot_clipping(&clip,&args)   modifiziert die Argumente passend fⁿr gr_dot
  100. # box_clipping(&clip,&args)   modifiziert die Argumente passend fⁿr gr_box
  101. # line_clipping(&clip,&args)  modifiziert die Argumente passend fⁿr gr_line
  102. # Rⁿckgabewert ist jeweils 0, wenn ⁿberhaupt nichts zu zeichnen ist, sonst 1.
  103.  
  104. struct clip
  105. {
  106.     sintL x1, x2;  # Bereich x1 <= x <= x2 (x1,x2 >= 0)
  107.     sintL y1, y2;  # Bereich y1 <= y <= y2 (y1,y2 >= 0)
  108.     # Bei x1 > x2 oder y1 > y2 ist der Bereich leer.
  109. };
  110.  
  111. struct dot_args
  112. {
  113.     sintL x, y;    # Pixel (x,y)
  114. };
  115.  
  116. struct box_args
  117. {
  118.     sintL xa, ya, xb, yb; # alle Pixel im Rechteck mit Ecken (xa,ya) und (xb,yb)
  119. };
  120.  
  121. struct line_args
  122. {
  123.     sintL xa, ya, xb, yb; # Linie von (xa,ya) bis (xb,yb)
  124. };
  125.  
  126. local int dot_clipping (const struct clip * clip, const struct dot_args * args);
  127. local int dot_clipping(clip,args)
  128.     var const struct clip * clip;
  129.     var const struct dot_args * args;
  130. {
  131.     return    (clip->x1 <= args->x) && (args->x <= clip->x2)
  132.            && (clip->y1 <= args->y) && (args->y <= clip->y2);
  133. }
  134.  
  135. local int box_clipping (const struct clip * clip, struct box_args * args);
  136. local int box_clipping(clip,args)
  137.     var const struct clip * clip;
  138.     var struct box_args * args;
  139. {
  140.     sintL xa, ya, xb, yb;
  141.     # Clipping in x-Richtung:
  142.     if (args->xa <= args->xb)
  143.       { xa = args->xa; xb = args->xb; }
  144.       else
  145.       { xa = args->xb; xb = args->xa; }
  146.     if (xa < clip->x1)
  147.       xa = clip->x1;
  148.     if (xb > clip->x2)
  149.       xb = clip->x2;
  150.     if (xa > xb)
  151.       return 0;
  152.     args->xa = xa; args->xb = xb;
  153.     # Clipping in y-Richtung:
  154.     if (args->ya <= args->yb)
  155.       { ya = args->ya; yb = args->yb; }
  156.       else
  157.       { ya = args->yb; yb = args->ya; }
  158.     if (ya < clip->y1)
  159.       ya = clip->y1;
  160.     if (yb > clip->y2)
  161.       yb = clip->y2;
  162.     if (ya > yb)
  163.       return 0;
  164.     args->ya = ya; args->yb = yb;
  165.     # Fertig.
  166.     return 1;
  167. }
  168.  
  169. # Liefert zu a,b>=0, c>0 (alle <2^31):  round(a * b / c) = floor(2*a*b+c,2*c)
  170. local sintL dreisatz (uintL a, uintL b, uintL c);
  171. local sintL dreisatz(a,b,c)
  172.     var uintL a;
  173.     var uintL b;
  174.     var uintL c;
  175. {
  176.     uintL hi, lo;
  177.     mulu32(a,2*b, hi=,lo=); # 2^32*hi + lo = 2*a*b
  178.     if ((lo += c) < c) { hi += 1; } # 2^32*hi + lo = 2*a*b + c
  179.     if (hi < c) # avoid overflow
  180.       { uintL q;
  181.         divu_6432_3232(hi,lo,2*c, q=,);
  182.         if ((sintL)q >= 0)
  183.           return q;
  184.       }
  185.     return (1UL<<31)-1;
  186. }
  187.  
  188. local int line_clipping (const struct clip * clip, struct line_args * args);
  189. local int line_clipping(clip,args)
  190.     var const struct clip * clip;
  191.     var struct line_args * args;
  192. {
  193.     sintL xa, ya, xb, yb;
  194.     sintL x1 = clip->x1;
  195.     sintL x2 = clip->x2;
  196.     sintL y1 = clip->y1;
  197.     sintL y2 = clip->y2;
  198.     # Check whether x1 <= x2 and y1 <= y2.
  199.     if ((x1 > x2) || (y1 > y2))
  200.       return 0;
  201.     # Ensure xa <= xb.
  202.     if (args->xa <= args->xb)
  203.       { xa = args->xa; ya = args->ya; xb = args->xb; yb = args->yb; }
  204.       else
  205.       { xa = args->xb; ya = args->yb; xb = args->xa; yb = args->ya; }
  206.     # Line entirely outside the window, in the same sector?
  207.     if (   (xa > x2) # implies xb > x2 too
  208.         || (xb < x1) # implies xa < x1 too
  209.         || (ya < y1 && yb < y1)
  210.         || (ya > y2 && yb > y2)
  211.        )
  212.       return 0;
  213.     # Line entirely inside the window?
  214.     if (xa >= x1 && xb <= x2 && ya >= y1 && ya <= y2 && yb >= y1 && yb <= y2)
  215.       goto ok;
  216.     # Special case horizontal line
  217.     if (ya == yb)
  218.       { if (xa < x1) xa = x1;
  219.         if (xb > x2) xb = x2;
  220.         goto ok;
  221.       }
  222.     # Special case vertical line
  223.     if (xa == xb)
  224.       { if (ya < y1) ya = y1;
  225.         elif (ya > y2) ya = y2;
  226.         if (yb < y1) yb = y1;
  227.         elif (yb > y2) yb = y2;
  228.         goto ok;
  229.       }
  230.     # Move left starting point into the clip rectangle.
  231.     if (xa < x1 || ya < y1 || ya > y2)
  232.       { # try to intersect line with left border
  233.         sintL y;
  234.         if (ya < yb)
  235.           { if ((xa < x1)
  236.                 && ((y = ya + dreisatz(x1-xa, yb-ya, xb-xa)) >= y1)
  237.                )
  238.               { if (y > y2)
  239.                   return 0;
  240.                 xa = x1; ya = y;
  241.               }
  242.             elif (ya < y1)
  243.               { xa = xa + dreisatz(y1-ya, xb-xa, yb-ya); ya = y1; }
  244.           }
  245.           else # ya > yb
  246.           { if ((xa < x1)
  247.                 && ((y = ya - dreisatz(x1-xa, ya-yb, xb-xa)) <= y2)
  248.                )
  249.               { if (y < y1)
  250.                   return 0;
  251.                 xa = x1; ya = y;
  252.               }
  253.             elif (ya > y2)
  254.               { xa = xa + dreisatz(ya-y2, xb-xa, ya-yb); ya = y2; }
  255.           }
  256.       }
  257.     # Move right starting point into the clip rectangle.
  258.     if (xb > x2 || yb < y1 || yb > y2)
  259.       { # try to intersect line with right border
  260.         sintL y;
  261.         if (ya < yb)
  262.           { if ((xb > x2)
  263.                 && ((y = yb - dreisatz(xb-x2, yb-ya, xb-xa)) <= y2)
  264.                )
  265.               { if (y < y1)
  266.                   return 0;
  267.                 xb = x2; yb = y;
  268.               }
  269.             elif (yb > y2)
  270.               { xb = xb - dreisatz(yb-y2, xb-xa, yb-ya); yb = y2; }
  271.           }
  272.           else # ya > yb
  273.           { if ((xb > x2)
  274.                 && ((y = yb + dreisatz(xb-x2, ya-yb, xb-xa)) >= y1)
  275.                )
  276.               { if (y > y2)
  277.                   return 0;
  278.                 xb = x2; yb = y;
  279.               }
  280.             elif (yb < y1)
  281.               { xb = xb - dreisatz(y1-yb, xb-xa, ya-yb); yb = y1; }
  282.           }
  283.       }
  284.     ok:
  285.     args->xa = xa; args->ya = ya; args->xb = xb; args->yb = yb;
  286.     return 1;
  287. }
  288.  
  289.  
  290. #ifdef GRAPHICS_SWITCH
  291.  
  292. # Ein Text-Bildschirm und ein Grafik-Bildschirm k÷nnen sichtbar sein, jedoch
  293. # nicht gleichzeitig.
  294. # switch_text_mode(); wechselt auf den Text-Bildschirm.
  295. # switch_graphics_mode(); wechselt auf den Grafik-Bildschirm.
  296. extern void switch_text_mode (void);
  297. extern void switch_graphics_mode (void);
  298.  
  299.  
  300. #ifdef EMUNIX_PORTABEL
  301.  
  302.  
  303. #include <graph.h>
  304. extern unsigned char *_g_mem;
  305.  
  306. #ifdef EMUNIX_NEW_9a
  307. /* see emx/src/lib/graph1.c, emx/src/lib/graph2.h, emx/src/lib/ega.h */
  308. #include <stdlib.h>
  309. #include <graph.h>
  310. #include <dos.h>
  311. #include <memory.h>
  312. #include <sys/hw.h>
  313. #define INCL_DOSMEMMGR
  314. #define INCL_DOSPROCESS
  315. #define INCL_VIO
  316. #include <os2emx.h>
  317. #include <os2thunk.h>
  318. extern int _g_locklevel;
  319. #define GLOCK  \
  320.   if (_osmode == OS2_MODE && _g_locklevel == 0) \
  321.     { unsigned char not_locked; VioScrLock (LOCKIO_WAIT, ¬_locked, 0); }
  322. #define GUNLOCK  \
  323.   if (_osmode == OS2_MODE && _g_locklevel == 0) \
  324.     { VioScrUnLock (0); }
  325. #endif
  326.  
  327. # The following modes are provided by the graph.a library:
  328. # G_MODE_OFF (text)
  329. # G_MODE_VGA_L (320x200x256)
  330. #ifdef EMUNIX_NEW_9a
  331. # G_MODE_EGA_C (640x200x16)
  332. # G_MODE_EGA_E (640x350x16)
  333. # G_MODE_VGA_H (640x480x16)
  334. #endif
  335.  
  336. #define GRAPH_SIZE_L  (320*200)
  337. #ifdef EMUNIX_NEW_9a
  338. #define GRAPH_SIZE_C  (640*200/2)
  339. #define GRAPH_SIZE_E  (640*350/2)
  340. #define GRAPH_SIZE_H  (640*480/2)
  341. #define GRAPH_SIZE_MAX  GRAPH_SIZE_H
  342. #else
  343. #define GRAPH_SIZE_MAX  GRAPH_SIZE_L
  344. #endif
  345.  
  346. int cur_mode = G_MODE_OFF;   /* current video mode       */
  347. int flip_mode = G_MODE_OFF;  /* flipped video mode       */
  348. unsigned char * graph_buf;   /* saves graphics data during flip */
  349. static struct clip cur_clip; /* current whole-screen clipping */
  350.  
  351. static int initialized = 0;
  352.  
  353. static int initialize (void)
  354. {
  355.     if ((graph_buf = malloc(GRAPH_SIZE_MAX)) == NULL)
  356.         { errno = ENOMEM; return -1; }
  357.     initialized = 1;
  358.     return 0;
  359. }
  360.  
  361. void switch_text_mode (void)
  362. {
  363.     if (cur_mode == G_MODE_OFF)
  364.         return;
  365.     /* cur_mode != G_MODE_OFF, so flip_mode == G_MODE_OFF,
  366.        and initialize() has already been called. */
  367. #ifdef EMUNIX_NEW_9a
  368.     if (cur_mode != GRAPH_SIZE_L)
  369.       { /* save 4 bitplanes separately */
  370.         int plane;
  371.         int plane_size = g_xsize * g_ysize / 8;
  372.         char* bufptr = graph_buf;
  373.         GLOCK;
  374.         _outp16 (0x3ce, 0x0304); /* bit plane 3 */
  375.         memcpy(bufptr,_g_mem,plane_size); bufptr += plane_size;
  376.         _outp8 (0x3cf, 0x02); /* bit plane 2 */
  377.         memcpy(bufptr,_g_mem,plane_size); bufptr += plane_size;
  378.         _outp8 (0x3cf, 0x01); /* bit plane 1 */
  379.         memcpy(bufptr,_g_mem,plane_size); bufptr += plane_size;
  380.         _outp8 (0x3cf, 0x00); /* bit plane 0 */
  381.         memcpy(bufptr,_g_mem,plane_size);
  382.         GUNLOCK;
  383.       }
  384.     else
  385. #endif
  386.       memcpy(graph_buf,_g_mem,GRAPH_SIZE_L);
  387.     flip_mode = cur_mode;
  388.     g_mode(G_MODE_OFF); cur_mode = G_MODE_OFF;
  389. }
  390.  
  391. void switch_graphics_mode (void)
  392. {
  393.     if (flip_mode == G_MODE_OFF)
  394.         return;
  395.     /* flip_mode != G_MODE_OFF, so cur_mode == G_MODE_OFF,
  396.        and initialize() has already been called. */
  397.     g_mode(flip_mode); cur_mode = flip_mode;
  398.     cur_clip.x1 = 0; cur_clip.x2 = g_xsize-1;
  399.     cur_clip.y1 = 0; cur_clip.y2 = g_ysize-1;
  400. #ifdef EMUNIX_NEW_9a
  401.     if (cur_mode != GRAPH_SIZE_L)
  402.       { /* restore 4 bitplanes separately */
  403.         int plane;
  404.         int plane_size = g_xsize * g_ysize / 8;
  405.         char* bufptr = graph_buf;
  406.         GLOCK;
  407.         _outp16 (0x3c4, 0x0802); /* bit plane 3 */
  408.         memcpy(_g_mem,bufptr,plane_size); bufptr += plane_size;
  409.         _outp8 (0x3c5, 0x04); /* bit plane 2 */
  410.         memcpy(_g_mem,bufptr,plane_size); bufptr += plane_size;
  411.         _outp8 (0x3c5, 0x02); /* bit plane 1 */
  412.         memcpy(_g_mem,bufptr,plane_size); bufptr += plane_size;
  413.         _outp8 (0x3c5, 0x01); /* bit plane 0 */
  414.         memcpy(_g_mem,bufptr,plane_size);
  415.         GUNLOCK;
  416.       }
  417.     else
  418. #endif
  419.       memcpy(_g_mem,graph_buf,GRAPH_SIZE);
  420.     flip_mode = G_MODE_OFF;
  421. }
  422.  
  423. int gr_init (sintL width, sintL height, sintL colors)
  424. {
  425.     int mode;
  426.     if (!initialized)
  427.         if (initialize())
  428.             { OS_error(); }
  429.     #ifdef EMUNIX_NEW_9a
  430.     if (colors <= 16)
  431.       { # choose a 16-color mode if possible
  432.         if (height > 350)
  433.           { mode = G_MODE_VGA_H; }
  434.         elif (height > 200)
  435.           { mode = G_MODE_EGA_E; }
  436.         elif (width > 320)
  437.           { mode = G_MODE_EGA_C; }
  438.         else
  439.           { mode = G_MODE_VGA_L; }
  440.       }
  441.       else
  442.     #endif
  443.       { # choose a 256-color mode
  444.         mode = G_MODE_VGA_L;
  445.       }
  446.     if (!g_mode(mode))
  447.         return -1;
  448.     flip_mode = G_MODE_OFF; cur_mode = mode;
  449.     cur_clip.x1 = 0; cur_clip.x2 = g_xsize-1;
  450.     cur_clip.y1 = 0; cur_clip.y2 = g_ysize-1;
  451.     return 0;
  452. }
  453.  
  454. void gr_show (void)
  455. {
  456.     if (cur_mode == G_MODE_OFF)
  457.       { switch_graphics_mode();
  458.         if (cur_mode == G_MODE_OFF)
  459.           { fehler(error,
  460.                    DEUTSCH ? "Grafik nicht initialisiert." :
  461.                    ENGLISH ? "graphics not initialized" :
  462.                    FRANCAIS ? "SystΦme graphique non initialisΘ." :
  463.                    ""
  464.                   );
  465.       }   }
  466. }
  467.  
  468. static struct named_color EGA_colors []
  469.   = { { G_BLACK,                 "BLACK"         },
  470.       { G_BLUE,                  "BLUE"          },
  471.       { G_GREEN,                 "GREEN"         },
  472.       { G_CYAN,                  "CYAN"          },
  473.       { G_RED,                   "RED"           },
  474.       { G_MAGENTA,               "MAGENTA"       },
  475.       { G_BROWN,                 "BROWN"         },
  476.       { G_WHITE,                 "LIGHT-GRAY"    },
  477.       { G_INTENSITY | G_BLACK,   "DARK-GRAY"     },
  478.       { G_INTENSITY | G_BLUE,    "LIGHT-BLUE"    },
  479.       { G_INTENSITY | G_GREEN,   "LIGHT-GREEN"   },
  480.       { G_INTENSITY | G_CYAN,    "LIGHT-CYAN"    },
  481.       { G_INTENSITY | G_RED,     "LIGHT-RED"     },
  482.       { G_INTENSITY | G_MAGENTA, "LIGHT-MAGENTA" },
  483.       { G_INTENSITY | G_YELLOW,  "YELLOW"        },
  484.       { G_INTENSITY | G_WHITE,   "WHITE"         },
  485.       { 0,                       NULL            }
  486.     };
  487.  
  488. struct named_color * gr_colors (void)
  489. {
  490.     return &!EGA_colors;
  491. }
  492.  
  493. #define gr_xdim  g_xsize
  494. #define gr_ydim  g_ysize
  495.  
  496. int gr_get (sintL x, sintL y)
  497. {
  498.     int color;
  499.     gr_show();
  500.     color = g_get(x,y);
  501.     if (color < 0)
  502.         color = G_BLACK;
  503.     return color;
  504. }
  505.  
  506. void gr_dot (sintL color, sintL x, sintL y)
  507. {
  508.     gr_show();
  509.     if (color >= 0 && color < g_colors)
  510.         g_set(x,y,color);
  511. }
  512.  
  513. void gr_box (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  514. {
  515.     gr_show();
  516.     if (color >= 0 && color < g_colors)
  517.         g_box(x1,y1,x2,y2,color,G_FILL);
  518. }
  519.  
  520. void gr_clear (sintL color)
  521. {
  522.     gr_show();
  523.     if (color >= 0 && color < g_colors)
  524.         g_clear(color);
  525. }
  526.  
  527. void gr_line (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  528. {
  529.     # Clipping selber durchfⁿhren; dem EMX-Clipping trauen wir nicht.
  530.     struct clip clip;
  531.     struct line_args args;
  532.     gr_show();
  533.     args.xa = x1; args.ya = y1; args.xb = x2; args.yb = y2;
  534.     if (color >= 0 && color < g_colors)
  535.       if (line_clipping(&cur_clip,&args))
  536.         g_line(args.xa,args.ya,args.xb,args.yb,color);
  537. }
  538.  
  539.  
  540. #else # (EMUNIX && !EMUNIX_PORTABEL) || UNIX_LINUX
  541.  
  542.  
  543. #ifdef UNIX
  544.  
  545. # Um Zugriff auf I/O-Ports und den Bildschirmspeicher zu haben, mu▀ das
  546. # Programm mit "setuid root"-Privileg installiert werden.
  547.  
  548. global uid_t root_uid; # wird von SPVW initialisiert
  549.  
  550. #define BEGIN_ROOT_PRIV  \
  551.   set_break_sem_1(); \
  552.   setreuid(user_uid,root_uid);
  553.  
  554. #define END_ROOT_PRIV  \
  555.   setreuid(root_uid,user_uid); \
  556.   clr_break_sem_1();
  557.  
  558. #endif
  559.  
  560. #ifdef EMUNIX
  561.  
  562. # INT 10 documentation:
  563. #   INT 10,01 - Set cursor type
  564. #   INT 10,03 - Read Cursor Position and Size
  565. #   INT 10,0F - Get current video state
  566. #   INT 10,12 - Video subsystem configuration (EGA/VGA)
  567. #   INT 10,1A - Video Display Combination (VGA)
  568. #
  569. # INT 10,01 - Set Cursor Type
  570. #     AH = 01
  571. #     CH = cursor starting scan line (cursor top) (low order 5 bits)
  572. #     CL = cursor ending scan line (cursor bottom) (low order 5 bits)
  573. #     returns nothing
  574. #     - cursor scan lines are zero based
  575. #     - the following is a list of the cursor scan lines associated with
  576. #       most common adapters;  screen sizes over 40 lines may differ
  577. #       depending on adapters.
  578. #               Line     Starting     Ending      Character
  579. #       Video   Count    Scan Line    Scan Line   Point Size
  580. #       CGA      25         06           07           08
  581. #       MDA      25         0B           0C           0E
  582. #       EGA      25         06           07           0E
  583. #       EGA      43       04/06          07           08
  584. #       VGA      25         0D           0E           10
  585. #       VGA      40         08           09           0A
  586. #       VGA      50         06           07           08
  587. #     - use CX = 2000h to disable cursor
  588. #
  589. # INT 10,03 - Read Cursor Position and Size
  590. #     AH = 03
  591. #     BH = video page
  592. #     on return:
  593. #     CH = cursor starting scan line (low order 5 bits)
  594. #     CL = cursor ending scan line (low order 5 bits)
  595. #     DH = row
  596. #     DL = column
  597. #
  598. # INT 10,0F - Get Video State
  599. #     AH = 0F
  600. #     on return:
  601. #     AH = number of screen columns
  602. #     AL = mode currently set (see ~VIDEO MODES~)
  603. #     BH = current display page
  604. #     - video modes greater than 13h on EGA, MCGA and VGA indicate
  605. #       ~INT 10,0~ was called with the high bit of the mode (AL) set
  606. #       to 1, meaning the display does not need cleared
  607. #     - function returns byte value at 40:49;  On EGA, MCGA and
  608. #       VGA bit 7 of register AL is determined by bit 7 of BIOS Data
  609. #       Area byte 40:87.   This bit is usually set by INT 10,0
  610. #       with bit 7 of the requested mode (in AL) set to 1
  611. #
  612. # INT 10,12 - Video Subsystem Configuration (EGA/VGA)
  613. #     AH = 12h
  614. #     BL = 10  return video configuration information
  615. #     on return:
  616. #     BH = 0 if color mode in effect
  617. #        = 1 if mono mode in effect
  618. #     BL = 0 if 64k EGA memory
  619. #        = 1 if 128k EGA memory
  620. #        = 2 if 192k EGA memory
  621. #        = 3 if 256k EGA memory
  622. #     CH = feature bits
  623. #     CL = switch settings
  624. #
  625. # INT 10,1A - Video Display Combination (VGA)
  626. #     AH = 1A
  627. #     AL = 00 get video display combination
  628. #        = 01 set video display combination
  629. #          BL = active display  (see table below)
  630. #          BH = inactive display
  631. #     on return:
  632. #     AL = 1A, if a valid function was requested in AH
  633. #     BL = active display  (AL=00, see table below)
  634. #     BH = inactive display  (AL=00)
  635. #     Valid display codes:
  636. #       FF  Unrecognized video system
  637. #       00  No display
  638. #       01  MDA with monochrome display
  639. #       02  CGA with color display
  640. #       03  Reserved
  641. #       04  EGA with color display
  642. #       05  EGA with monochrome display
  643. #       06  Professional graphics controller
  644. #       07  VGA with analog monochrome display
  645. #       08  VGA with analog color display
  646. #       09  Reserved
  647. #       0A  MCGA with digital color display
  648. #       0B  MCGA with analog monochrome display
  649. #       0C  MCGA with analog color display
  650. #     - returns value at byte 40:8A indicating display combination status
  651. #     - used to detect video display capabilities
  652.  
  653. # Perform an INT 10
  654.   static void intvideo (union REGS * in_regs, union REGS * out_regs);
  655.   static void intvideo(in_regs,out_regs)
  656.     var register union REGS * in_regs;
  657.     var register union REGS * out_regs;
  658.     { __asm__ __volatile__ ( "movl 0(%%esi),%%eax ; "
  659.                              "movl 4(%%esi),%%ebx ; "
  660.                              "movl 8(%%esi),%%ecx ; "
  661.                              "movl 12(%%esi),%%edx ; "
  662.                              "pushl %%edi ; "
  663.                              ".byte 0xcd ; .byte 0x10 ; "
  664.                              "popl %%edi ; "
  665.                              "movl %%eax,0(%%edi) ; "
  666.                              "movl %%ebx,4(%%edi) ; "
  667.                              "movl %%ecx,8(%%edi) ; "
  668.                              "movl %%edx,12(%%edi)"
  669.                              :                                                         # OUT
  670.                              : "S" /* %esi */ (in_regs), "D" /* %edi */ (out_regs)     # IN
  671.                              : "ax","bx","cx","si","di" /* %eax,%ebx,%ecx,%esi,%edi */ # CLOBBER
  672.                            );
  673.     }
  674.  
  675. # Some variables used for saving the text data during flip
  676. static unsigned long text_phys_mem; /* physical address of text video RAM */
  677. static unsigned long text_size;     /* size of text data */
  678. static unsigned short * text_mem;   /* address of text video RAM */
  679. static unsigned short * text_buf;   /* buffer for text data */
  680. static unsigned short text_cursor_shape; /* text cursor shape */
  681. static int text_saved = 0; /* flag: does text_buf contain the text data? */
  682.  
  683. # Enquire text mode settings
  684. static void get_text_info (void);
  685. static void get_text_info()
  686.   { var unsigned char video_mode;
  687.     var unsigned int video_cols;
  688.     var unsigned int video_rows;
  689.     var int vga_present;
  690.     var union REGS in;
  691.     var union REGS out;
  692.     in.regB.ah = 0x0F; intvideo(&in,&out); # INT 10,0F : get current video state
  693.     video_mode = out.regB.al & 0x7f; video_cols = out.regB.ah; video_rows = 25;
  694.     { var int scrsize[2];
  695.       _scrsize(&!scrsize);
  696.       if (scrsize[0] > 0) { video_cols = scrsize[0]; }
  697.       if (scrsize[1] > 0) { video_rows = scrsize[1]; }
  698.     }
  699.     # check for VGA
  700.     vga_present = 0;
  701.     #if 0 # EMX doesn't allow this BIOS call
  702.     in.regB.ah = 0x12; in.regB.bl = 0x10; intvideo(&in,&out); # INT 10,12: check for EGA/VGA
  703.     if (!(out.regB.bl == 0x10))
  704.     #endif
  705.       { in.regB.ah = 0x1A; in.regB.al = 0x00; intvideo(&in,&out); # INT 10,1A: check for VGA
  706.         if (!(out.regB.al == 0x1A))
  707.           { vga_present = 1; } # check for SVGA??
  708.       }
  709.     text_size = video_rows * video_cols;
  710.     if (video_mode == 7) # monochrome?
  711.       { text_phys_mem = 0xB0000;
  712.         # if (vga_present)
  713.         #   { 0xB0000..0xB7FFF } # EGA/VGA in Mono mode
  714.         #   else
  715.         #   { 0xB0000..0xB1FFF } # MDA
  716.       }
  717.       else # color
  718.       { text_phys_mem = 0xB8000;
  719.         # if (vga_present)
  720.         #   { 0xB8000..0xBFFFF } # EGA/VGA in Color mode
  721.         #   else
  722.         #   { 0xB8000..0xB9FFF } # CGA
  723.       }
  724.   }
  725.  
  726. static void memsetw (unsigned short * s, unsigned short c, int count);
  727. static inline void memsetw(s,c,count)
  728.   var unsigned short * s;
  729.   var unsigned short c;
  730.   var int count;
  731.   { __asm__ __volatile__ ("cld ; rep ; stosw"
  732.                           :
  733.                           : "a" /* %ax */ (c), /* %edi */ "D" (s), /* %ecx */ "c" (count)
  734.                           : /* %ecx */ "cx", /* %edi */ "di"
  735.                          );
  736.   }
  737.  
  738. # Equivalent to Linux ioctl KD_GRAPHICS: save text data.
  739. static void kd_graphics (void);
  740. static void kd_graphics()
  741.   { if (text_saved) return;
  742.     # save text data
  743.     memcpy(text_buf,text_mem,2*text_size);
  744.     # hide cursor
  745.     { var union REGS in;
  746.       var union REGS out;
  747.       in.regB.ah = 0x03; in.regB.bh = 0x00; intvideo(&in,&out); # INT 10,03 : read cursor shape
  748.       text_cursor_shape = out.regW.cx;
  749.       in.regB.ah = 0x01; in.regW.cx = 0x2000; intvideo(&in,&out); # INT 10,01 : set cursor type
  750.     }
  751.     text_saved = 1;
  752.     # clear text screen
  753.     memsetw(text_mem,0x0020,text_size);
  754.   }
  755.  
  756. # Equivalent to Linux ioctl KD_TEXT: restore text data.
  757. static void kd_text (void);
  758. static void kd_text()
  759.   { if (!text_saved) return;
  760.     # restore text data
  761.     memcpy(text_mem,text_buf,2*text_size);
  762.     # show cursor
  763.     { var union REGS in;
  764.       var union REGS out;
  765.       in.regB.ah = 0x01; in.regW.cx = text_cursor_shape; intvideo(&in,&out); # INT 10,01 : set cursor type
  766.     }
  767.     text_saved = 0;
  768.   }
  769.  
  770. #endif
  771.  
  772.  
  773. # =========================== vgalib/vga.h =================================== #
  774.  
  775. /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
  776. /*                                                                 */
  777. /* This library is free software; you can redistribute it and/or   */
  778. /* modify it without any restrictions. This library is distributed */
  779. /* in the hope that it will be useful, but without any warranty.   */
  780.  
  781. #define TEXT         0
  782. #define G320x200x16  1
  783. #define G640x200x16  2
  784. #define G640x350x16  3
  785. #define G640x480x16  4
  786. #define G320x200x256 5
  787. #define G320x240x256 6
  788. #define G320x400x256 7
  789. #define G360x480x256 8
  790. #define G640x480x2   9
  791.  
  792. #define G640x480x256  10
  793. #define G800x600x256  11
  794. #define G1024x768x256 12
  795.  
  796. extern int vga_setmode (int mode);
  797. extern int vga_hasmode (int mode);
  798.  
  799. extern void vga_clear (void);
  800.  
  801. extern int vga_getxdim (void);
  802. extern int vga_getydim (void);
  803. extern int vga_getcolors (void);
  804.  
  805. extern void vga_screenoff (void);
  806. extern void vga_screenon (void);
  807.  
  808. extern void switch_text_mode (void);
  809. extern void switch_graphics_mode (void);
  810.  
  811. extern void vga_setcolor (int color);
  812. extern void vga_drawpixel (int x, int y);
  813. extern void vga_drawhline (int x1, int x2, int y);
  814. extern void vga_drawbox (int x1, int y1, int x2, int y2);
  815. extern void vga_drawline (int x1, int y1, int x2, int y2);
  816. #if 0
  817. extern void vga_drawscanline (int line, unsigned char* colors);
  818. extern void vga_drawscansegment (unsigned char* colors, int x, int y, int length);
  819. #endif
  820.  
  821.  
  822. # =========================== vgalib/vga.c =================================== #
  823.  
  824. /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
  825. /*                                                                 */
  826. /* This library is free software; you can redistribute it and/or   */
  827. /* modify it without any restrictions. This library is distributed */
  828. /* in the hope that it will be useful, but without any warranty.   */
  829.  
  830. #ifdef UNIX
  831.   #include <sys/kd.h>
  832. #endif
  833. #ifdef EMUNIX
  834.   #include <sys/hw.h>  /* declares _portaccess(), _memaccess() */
  835.   /* Ensure that the arguments to _memaccess() are page-aligned */
  836.   #define memaccess(first,last,flag)  \
  837.     _memaccess((first) & ~0xfff, (last) | 0xfff, flag)
  838. #endif
  839.  
  840. #define uchar unsigned char
  841.  
  842. #define GRAPH_BASE 0xA0000
  843. #define GRAPH_SIZE 0x10000
  844. #define FONT_BASE  0xA0000
  845. #define FONT_SIZE  0x2000
  846. #define NULL_SIZE  0x1000
  847.  
  848. #define MAX_REGS 100
  849.  
  850. /* VGA index register ports */
  851. #define CRT_IC  0x3D4   /* CRT Controller Index - color emulation */
  852. #define CRT_IM  0x3B4   /* CRT Controller Index - mono emulation */
  853. #define ATT_IW  0x3C0   /* Attribute Controller Index & Data Write Register */
  854. #define GRA_I   0x3CE   /* Graphics Controller Index */
  855. #define SEQ_I   0x3C4   /* Sequencer Index */
  856. #define PEL_IW  0x3C8   /* PEL Write Index */
  857. #define PEL_IR  0x3C7   /* PEL Read Index */
  858.  
  859. /* VGA data register ports */
  860. #define CRT_DC  0x3D5   /* CRT Controller Data Register - color emulation */
  861. #define CRT_DM  0x3B5   /* CRT Controller Data Register - mono emulation */
  862. #define ATT_R   0x3C1   /* Attribute Controller Data Read Register */
  863. #define GRA_D   0x3CF   /* Graphics Controller Data Register */
  864. #define SEQ_D   0x3C5   /* Sequencer Data Register */
  865. #define MIS_R   0x3CC   /* Misc Output Read Register */
  866. #define MIS_W   0x3C2   /* Misc Output Write Register */
  867. #define IS1_RC  0x3DA   /* Input Status Register 1 - color emulation */
  868. #define IS1_RM  0x3BA   /* Input Status Register 1 - mono emulation */
  869. #define PEL_D   0x3C9   /* PEL Data Register */
  870.  
  871. /* VGA indexes max counts */
  872. #define CRT_C   24      /* 24 CRT Controller Registers */
  873. #define ATT_C   21      /* 21 Attribute Controller Registers */
  874. #define GRA_C   9       /* 9  Graphics Controller Registers */
  875. #define SEQ_C   5       /* 5  Sequencer Registers */
  876. #define MIS_C   1       /* 1  Misc Output Register */
  877.  
  878. /* VGA registers saving indexes */
  879. #define CRT     0               /* CRT Controller Registers start */
  880. #define ATT     CRT+CRT_C       /* Attribute Controller Registers start */
  881. #define GRA     ATT+ATT_C       /* Graphics Controller Registers start */
  882. #define SEQ     GRA+GRA_C       /* Sequencer Registers */
  883. #define MIS     SEQ+SEQ_C       /* General Registers */
  884. #define EXT     MIS+MIS_C       /* SVGA Extended Registers */
  885.  
  886. #define SEG_SELECT 0x3CD
  887.  
  888. #define ABS(a) (((a)<0) ? -(a) : (a))
  889.  
  890. /* variables used to shift between monchrome and color emulation */
  891. static int CRT_I;               /* current CRT index register address */
  892. static int CRT_D;               /* current CRT data register address */
  893. static int IS1_R;               /* current input status register address */
  894. static int color_text;          /* true if color text emulation */
  895.  
  896.  
  897. /* graphics mode information */
  898. struct info {
  899.     int xdim;
  900.     int ydim;
  901.     int colors;
  902.     int xbytes;
  903. };
  904.  
  905.  
  906. /* BIOS mode 0Dh - 320x200x16 */
  907. static uchar g320x200x16_regs[60] = {
  908.   0x2D,0x27,0x28,0x90,0x2B,0x80,0xBF,0x1F,0x00,0xC0,0x00,0x00,
  909.   0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x14,0x00,0x96,0xB9,0xE3,
  910.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  911.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  912.   0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
  913.   0x03,0x09,0x0F,0x00,0x06,
  914.   0x63
  915. };
  916. static struct info g320x200x16_info = { 320, 200, 16, 40 };
  917.  
  918.  
  919. /* BIOS mode 0Eh - 640x200x16 */
  920. static uchar g640x200x16_regs[60] = {
  921.   0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0xC0,0x00,0x00,
  922.   0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x00,0x96,0xB9,0xE3,
  923.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  924.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  925.   0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
  926.   0x03,0x01,0x0F,0x00,0x06,
  927.   0x63
  928. };
  929. static struct info g640x200x16_info = { 640, 200, 16, 80 };
  930.  
  931.  
  932. /* BIOS mode 10h - 640x350x16 */
  933. static uchar g640x350x16_regs[60] = {
  934.   0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x40,0x00,0x00,
  935.   0x00,0x00,0x00,0x00,0x83,0x85,0x5D,0x28,0x0F,0x63,0xBA,0xE3,
  936.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  937.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  938.   0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
  939.   0x03,0x01,0x0F,0x00,0x06,
  940.   0xA3
  941. };
  942. static struct info g640x350x16_info = { 640, 350, 16, 80 };
  943.  
  944.  
  945. /* BIOS mode 12h - 640x480x16 */
  946. static uchar g640x480x16_regs[60] = {
  947.   0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x00,0x00,
  948.   0x00,0x00,0x00,0x00,0xEA,0x8C,0xDF,0x28,0x00,0xE7,0x04,0xE3,
  949.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  950.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  951.   0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
  952.   0x03,0x01,0x0F,0x00,0x06,
  953.   0xE3
  954. };
  955. static struct info g640x480x16_info = { 640, 480, 16, 80 };
  956.  
  957.  
  958. /* BIOS mode 13h - 320x200x256 */
  959. static uchar g320x200x256_regs[60] = {
  960.   0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x41,0x00,0x00,
  961.   0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x40,0x96,0xB9,0xA3,
  962.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  963.   0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
  964.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  965.   0x03,0x01,0x0F,0x00,0x0E,
  966.   0x63
  967. };
  968. static struct info g320x200x256_info = { 320, 200, 256, 320 };
  969.  
  970.  
  971. /* non-BIOS mode - 320x240x256 */
  972. static uchar g320x240x256_regs[60] = {
  973.   0x5F,0x4F,0x50,0x82,0x54,0x80,0x0D,0x3E,0x00,0x41,0x00,0x00,
  974.   0x00,0x00,0x00,0x00,0xEA,0xAC,0xDF,0x28,0x00,0xE7,0x06,0xE3,
  975.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  976.   0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
  977.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  978.   0x03,0x01,0x0F,0x00,0x06,
  979.   0xE3
  980. };
  981. static struct info g320x240x256_info = { 320, 240, 256, 80 };
  982.  
  983.  
  984. /* non-BIOS mode - 320x400x256 */
  985. static uchar g320x400x256_regs[60] = {
  986.   0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,0x00,0x40,0x00,0x00,
  987.   0x00,0x00,0x00,0x00,0x9C,0x8E,0x8F,0x28,0x00,0x96,0xB9,0xE3,
  988.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  989.   0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
  990.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  991.   0x03,0x01,0x0F,0x00,0x06,
  992.   0x63
  993. };
  994. static struct info g320x400x256_info = { 320, 400, 256, 80 };
  995.  
  996.  
  997. /* non-BIOS mode - 360x480x256 */
  998. static uchar g360x480x256_regs[60] = {
  999.   0x6B,0x59,0x5A,0x8E,0x5E,0x8A,0x0D,0x3E,0x00,0x40,0x00,0x00,
  1000.   0x00,0x00,0x00,0x00,0xEA,0xAC,0xDF,0x2D,0x00,0xE7,0x06,0xE3,
  1001.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  1002.   0x0C,0x0D,0x0E,0x0F,0x41,0x00,0x0F,0x00,0x00,
  1003.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  1004.   0x03,0x01,0x0F,0x00,0x06,
  1005.   0xE7
  1006. };
  1007. static struct info g360x480x256_info = { 360, 480, 256, 90 };
  1008.  
  1009.  
  1010. /* monochrome mode based on BIOS mode 12h - 640x480x2 */
  1011. static uchar g640x480x2_regs[60] = {
  1012.   0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x00,0x00,
  1013.   0x00,0x00,0x00,0x00,0xEA,0x8C,0xDF,0x28,0x00,0xE7,0x04,0xE3,
  1014.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  1015.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  1016.   0x00,0x0F,0x00,0x20,0x00,0x00,0x05,0x0F,0xFF,
  1017.   0x03,0x01,0x0F,0x00,0x06,
  1018.   0xE3
  1019. };
  1020. static struct info g640x480x2_info = { 640, 480, 2, 80 };
  1021.  
  1022.  
  1023. /* ET4000 BIOS mode 2Eh - 640x480x256 */
  1024. static uchar g640x480x256_regs[70] = {
  1025.   0x5F,0x4F,0x50,0x82,0x54,0x80,0x0B,0x3E,0x00,0x40,0x00,0x00,
  1026.   0x00,0x00,0x00,0x00,0xEA,0x8C,0xDF,0x50,0x60,0xE7,0x04,0xAB,
  1027.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  1028.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  1029.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  1030.   0x03,0x01,0x0F,0x00,0x0E,
  1031.   0xE3,
  1032.   0x70,0x00,0x08,0x00,0x43,0x1F,0xBC,0x00,0x00,0x00
  1033. };
  1034. static struct info g640x480x256_info = { 640, 480, 256, 640 };
  1035.  
  1036.  
  1037. /* ET4000 BIOS mode 30h - 800x600x256 */
  1038. static uchar g800x600x256_regs[70] = {
  1039.   0x7A,0x63,0x64,0x1D,0x68,0x9A,0x78,0xF0,0x00,0x60,0x00,0x00,
  1040.   0x00,0x00,0x00,0x00,0x5C,0x8E,0x57,0x64,0x60,0x5B,0x75,0xAB,
  1041.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  1042.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  1043.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  1044.   0x03,0x01,0x0F,0x00,0x0E,
  1045.   0xEF,
  1046.   0x70,0x00,0x08,0x00,0x43,0x1F,0xBC,0x00,0x00,0x00
  1047. };
  1048. static struct info g800x600x256_info = { 800, 600, 256, 800 };
  1049.  
  1050.  
  1051. /* ET4000 BIOS mode 38h - 1024x768x256 */
  1052. static uchar g1024x768x256_regs[70] = {
  1053.   0x99,0x7F,0x7F,0x1D,0x83,0x17,0x2F,0xF5,0x00,0x60,0x00,0x00,
  1054.   0x00,0x00,0x00,0x00,0x08,0x80,0xFF,0x80,0x60,0xFF,0x30,0xAB,
  1055.   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
  1056.   0x0C,0x0D,0x0E,0x0F,0x01,0x00,0x0F,0x00,0x00,
  1057.   0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
  1058.   0x03,0x01,0x0F,0x00,0x0E,
  1059.   0x27,
  1060.   0x70,0x00,0x0A,0x80,0x43,0x1F,0xBC,0x00,0x00,0x00
  1061. };
  1062. static struct info g1024x768x256_info = { 1024, 768, 256, 1024 };
  1063.  
  1064.  
  1065. /* default palette values */
  1066. static uchar default_red[256]
  1067.              = { 0, 0, 0, 0,42,42,42,42,21,21,21,21,63,63,63,63,
  1068.                  0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  1069.                  0,16,31,47,63,63,63,63,63,63,63,63,63,47,31,16,
  1070.                  0, 0, 0, 0, 0, 0, 0, 0,31,39,47,55,63,63,63,63,
  1071.                 63,63,63,63,63,55,47,39,31,31,31,31,31,31,31,31,
  1072.                 45,49,54,58,63,63,63,63,63,63,63,63,63,58,54,49,
  1073.                 45,45,45,45,45,45,45,45, 0, 7,14,21,28,28,28,28,
  1074.                 28,28,28,28,28,21,14, 7, 0, 0, 0, 0, 0, 0, 0, 0,
  1075.                 14,17,21,24,28,28,28,28,28,28,28,28,28,24,21,17,
  1076.                 14,14,14,14,14,14,14,14,20,22,24,26,28,28,28,28,
  1077.                 28,28,28,28,28,26,24,22,20,20,20,20,20,20,20,20,
  1078.                  0, 4, 8,12,16,16,16,16,16,16,16,16,16,12, 8, 4,
  1079.                  0, 0, 0, 0, 0, 0, 0, 0, 8,10,12,14,16,16,16,16,
  1080.                 16,16,16,16,16,14,12,10, 8, 8, 8, 8, 8, 8, 8, 8,
  1081.                 11,12,13,15,16,16,16,16,16,16,16,16,16,15,13,12,
  1082.                 11,11,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0, 0};
  1083. static uchar default_green[256]
  1084.              = { 0, 0,42,42, 0, 0,21,42,21,21,63,63,21,21,63,63,
  1085.                  0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  1086.                  0, 0, 0, 0, 0, 0, 0, 0, 0,16,31,47,63,63,63,63,
  1087.                 63,63,63,63,63,47,31,16,31,31,31,31,31,31,31,31,
  1088.                 31,39,47,55,63,63,63,63,63,63,63,63,63,55,47,39,
  1089.                 45,45,45,45,45,45,45,45,45,49,54,58,63,63,63,63,
  1090.                 63,63,63,63,63,58,54,49, 0, 0, 0, 0, 0, 0, 0, 0,
  1091.                  0, 7,14,21,29,28,28,28,28,28,28,28,28,21,14, 7,
  1092.                 14,14,14,14,14,14,14,14,14,17,21,24,28,28,28,28,
  1093.                 28,28,28,28,28,24,21,17,20,20,20,20,20,20,20,20,
  1094.                 20,22,24,26,28,28,28,28,28,28,28,28,28,26,24,22,
  1095.                  0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,12,16,16,16,16,
  1096.                 16,16,16,16,16,12, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8,
  1097.                  8,10,12,14,16,16,16,16,16,16,16,16,16,14,12,10,
  1098.                 11,11,11,11,11,11,11,11,11,12,13,15,16,16,16,16,
  1099.                 16,16,16,16,16,15,13,12, 0, 0, 0, 0, 0, 0, 0, 0};
  1100. static uchar default_blue[256]
  1101.              = { 0,42, 0,42, 0,42, 0,42,21,63,21,63,21,63,21,63,
  1102.                  0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  1103.                 63,63,63,63,63,47,31,16, 0, 0, 0, 0, 0, 0, 0, 0,
  1104.                  0,16,31,47,63,63,63,63,63,63,63,63,63,55,47,39,
  1105.                 31,31,31,31,31,31,31,31,31,39,47,55,63,63,63,63,
  1106.                 63,63,63,63,63,58,54,49,45,45,45,45,45,45,45,45,
  1107.                 45,49,54,58,63,63,63,63,28,28,28,28,28,21,14, 7,
  1108.                  0, 0, 0, 0, 0, 0, 0, 0, 0, 7,14,21,28,28,28,28,
  1109.                 28,28,28,28,28,24,21,17,14,14,14,14,14,14,14,14,
  1110.                 14,17,21,24,28,28,28,28,28,28,28,28,28,26,24,22,
  1111.                 20,20,20,20,20,20,20,20,20,22,24,26,28,28,28,28,
  1112.                 16,16,16,16,16,12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0,
  1113.                  0, 4, 8,12,16,16,16,16,16,16,16,16,16,14,12,10,
  1114.                  8, 8, 8, 8, 8, 8, 8, 8, 8,10,12,14,16,16,16,16,
  1115.                 16,16,16,16,16,15,13,12,11,11,11,11,11,11,11,11,
  1116.                 11,12,13,15,16,16,16,16, 0, 0, 0, 0, 0, 0, 0, 0};
  1117.  
  1118.  
  1119. /* used to decompose color value into bits (for fast scanline drawing) */
  1120. union bits {
  1121.     struct {
  1122.         uchar bit3;
  1123.         uchar bit2;
  1124.         uchar bit1;
  1125.         uchar bit0;
  1126.     } b;
  1127.     unsigned int i;
  1128. };
  1129.  
  1130. /* color decompositions */
  1131. static union bits color16[16] = {{0,0,0,0},
  1132.                                  {0,0,0,1},
  1133.                                  {0,0,1,0},
  1134.                                  {0,0,1,1},
  1135.                                  {0,1,0,0},
  1136.                                  {0,1,0,1},
  1137.                                  {0,1,1,0},
  1138.                                  {0,1,1,1},
  1139.                                  {1,0,0,0},
  1140.                                  {1,0,0,1},
  1141.                                  {1,0,1,0},
  1142.                                  {1,0,1,1},
  1143.                                  {1,1,0,0},
  1144.                                  {1,1,0,1},
  1145.                                  {1,1,1,0},
  1146.                                  {1,1,1,1}};
  1147.  
  1148.  
  1149. static uchar text_regs[MAX_REGS];   /* VGA registers for saved text mode */
  1150.  
  1151. /* saved text mode palette values */
  1152. static uchar text_red[256];
  1153. static uchar text_green[256];
  1154. static uchar text_blue[256];
  1155.  
  1156. /* saved graphics mode palette values */
  1157. static uchar graph_red[256];
  1158. static uchar graph_green[256];
  1159. static uchar graph_blue[256];
  1160.  
  1161. static int         cur_mode  = TEXT;     /* current video mode       */
  1162. static int         flip_mode = TEXT;     /* flipped video mode       */
  1163. static struct info cur_info;             /* current video parameters */
  1164. static int         cur_color;            /* current color            */
  1165. static struct clip cur_clip;             /* current whole-screen clipping */
  1166.  
  1167. static int initialized = 0;   /* flag: initialize() called ?  */
  1168. static int et4000      = 0;   /* flag: ET4000 or standard VGA */
  1169.  
  1170. #ifdef UNIX
  1171. static int   tty0_fd;    /* /dev/tty0 file descriptor                 */
  1172. #endif
  1173. static uchar* graph_mem; /* dummy buffer for mmapping graphics memory */
  1174. static uchar* graph_buf; /* saves graphics data during flip           */
  1175.  
  1176. static uchar font_buf1[FONT_SIZE];  /* saved font data - plane 2 */
  1177. static uchar font_buf2[FONT_SIZE];  /* saved font data - plane 3 */
  1178. static uchar null_buf[NULL_SIZE];   /* used to speed up clear */
  1179.  
  1180.  
  1181. static inline void port_out (uchar value, unsigned short port)
  1182. {
  1183.         __asm__ volatile ("outb %0,%1"
  1184.                           :
  1185.                           : "a" ((uchar) value), "d" ((unsigned short) port));
  1186. }
  1187.  
  1188. static inline uchar port_in (unsigned short port)
  1189. {
  1190.         uchar _v;
  1191.         __asm__ volatile ("inb %1,%0"
  1192.                           : "=a" (_v)
  1193.                           : "d" ((unsigned short) port));
  1194.         return _v;
  1195. }
  1196.  
  1197.  
  1198. # There is a big problem:
  1199. #   Text output may not occur while the VGA hardware is in graphics mode.
  1200. #
  1201. # We distinguish
  1202. # a. text output from CLISP itself,
  1203. # b. text output from the OS, for example when the user types something,
  1204. # c. text output from other programs.
  1205. #
  1206. # a. Solved: We switch to text mode every time we are about to output
  1207. #    something to stdout. (See stream.d.)
  1208. # b. Solved: DOS/EMX doesn't output anything (local echo is not done until
  1209. #    the next read() call), Linux consoles are protected by KD_GRAPHICS.
  1210. # c. Partially solved: On exit, CLISP switches to text mode (see spvw.d).
  1211. #    Signals SIGTSTP, SIGTTIN, SIGTTOU are ignored, and signal SIGSTOP is
  1212. #    de facto disabled, using termios ioctl's.
  1213. #    But when other programs are called by CLISP (using SHELL, EXECUTE or
  1214. #    MAKE-PIPE-OUTPUT-STREAM), it is up to the user to ensure they don't do
  1215. #    any output!
  1216.  
  1217. #ifdef UNIX
  1218.  
  1219. static char suspend_char = 0; # the suspend character (normally Ctrl-Z)
  1220.  
  1221. static void set_graphmode_signals (void)
  1222. {
  1223.     begin_system_call();
  1224.     SIGNAL(SIGTSTP,SIG_IGN);
  1225.     SIGNAL(SIGTTIN,SIG_IGN);
  1226.     SIGNAL(SIGTTOU,SIG_IGN);
  1227.     { struct termios the_termio;
  1228.       if ( tcgetattr(stdin_handle,&the_termio) ==0)
  1229.         { if (!suspend_char && the_termio.c_cc[VSUSP])
  1230.             suspend_char = the_termio.c_cc[VSUSP];
  1231.           the_termio.c_cc[VSUSP] = 0; # disable suspend character
  1232.           TCSETATTR(stdin_handle,TCSAFLUSH,&the_termio);
  1233.     }   }
  1234.     end_system_call();
  1235. }
  1236.  
  1237. static void set_textmode_signals (void)
  1238. {
  1239.     begin_system_call();
  1240.     SIGNAL(SIGTSTP,SIG_DFL);
  1241.     SIGNAL(SIGTTIN,SIG_DFL);
  1242.     SIGNAL(SIGTTOU,SIG_DFL);
  1243.     if (suspend_char)
  1244.       { struct termios the_termio;
  1245.         if ( tcgetattr(stdin_handle,&the_termio) ==0)
  1246.           { # Be careful not to enable Ctrl-Z when we are in raw mode!
  1247.             if ((the_termio.c_lflag & ICANON) && !the_termio.c_cc[VSUSP])
  1248.               { the_termio.c_cc[VSUSP] = suspend_char; # re-enable suspend character
  1249.                 TCSETATTR(stdin_handle,TCSAFLUSH,&the_termio);
  1250.       }   }   }
  1251.     end_system_call();
  1252. }
  1253.  
  1254. #endif
  1255.  
  1256. #ifdef EMUNIX
  1257.  
  1258. # EMX doesn't have these signals.
  1259.  
  1260. static inline void set_graphmode_signals (void) {}
  1261. static inline void set_textmode_signals (void) {}
  1262.  
  1263. #endif
  1264.  
  1265.  
  1266. # When poking around in the VGA hardware, we need to disable the most critical
  1267. # interrupts. Well, we can't disable the scheduler, but we can block nearly
  1268. # all the signals and disable SIGSTOP.
  1269. # The macros disable_interrupts() and enable_interrupts() must be called in
  1270. # pairs, in the same block.
  1271.  
  1272. #ifdef UNIX
  1273.   #define disable_interrupts()  \
  1274.     { sigset_t old_sigmask, sigblock_mask;                 \
  1275.       sigfillset(&sigblock_mask);                          \
  1276.       sigprocmask(SIG_BLOCK,&sigblock_mask,&old_sigmask);  \
  1277.       { struct termios the_termio;                         \
  1278.         if ( tcgetattr(stdin_handle,&the_termio) ==0)      \
  1279.           { the_termio.c_lflag &= ~ISIG;                   \
  1280.             TCSETATTR(stdin_handle,TCSAFLUSH,&the_termio); \
  1281.       }   }
  1282.   #define enable_interrupts()  \
  1283.       { struct termios the_termio;                         \
  1284.         if ( tcgetattr(stdin_handle,&the_termio) ==0)      \
  1285.           { the_termio.c_lflag |= ISIG;                    \
  1286.             TCSETATTR(stdin_handle,TCSAFLUSH,&the_termio); \
  1287.       }   }                                                \
  1288.       sigprocmask(SIG_SETMASK,&old_sigmask,NULL);          \
  1289.     }
  1290. #endif
  1291. #ifdef EMUNIX
  1292.   # EMX doesn't have these signals.
  1293.   #define disable_interrupts()
  1294.   #define enable_interrupts()
  1295. #endif
  1296.  
  1297.  
  1298. # The next six functions should only be called with interrupts disabled.
  1299.  
  1300.  
  1301. # Get I/O port permissions.
  1302. static int get_perm()
  1303. {
  1304.     static int done = 0;
  1305.  
  1306.     if (!done)
  1307.         {
  1308.  
  1309.           #ifdef UNIX
  1310.           {
  1311.             int err = 0;
  1312.  
  1313.             BEGIN_ROOT_PRIV;
  1314.  
  1315.             /* get I/O permissions for VGA registers */
  1316.             if (ioperm(CRT_IC, 1, 1)
  1317.              || ioperm(CRT_IM, 1, 1)
  1318.              || ioperm(ATT_IW, 1, 1)
  1319.              || ioperm(GRA_I,  1, 1)
  1320.              || ioperm(SEQ_I,  1, 1)
  1321.              || ioperm(PEL_IW, 1, 1)
  1322.              || ioperm(PEL_IR, 1, 1)
  1323.              || ioperm(CRT_DC, 1, 1)
  1324.              || ioperm(CRT_DM, 1, 1)
  1325.              || ioperm(ATT_R,  1, 1)
  1326.              || ioperm(GRA_D,  1, 1)
  1327.              || ioperm(SEQ_D,  1, 1)
  1328.              || ioperm(MIS_R,  1, 1)
  1329.              || ioperm(MIS_W,  1, 1)
  1330.              || ioperm(IS1_RC, 1, 1)
  1331.              || ioperm(IS1_RM, 1, 1)
  1332.              || ioperm(PEL_D,  1, 1)
  1333.  
  1334.             /* ET4000 registers */
  1335.              || ioperm(0x3bf,  1, 1)
  1336.              || ioperm(0x3cc,  1, 1)
  1337.              || ioperm(0x3d8,  1, 1)
  1338.              || ioperm(0x3b8,  1, 1)
  1339.              || ioperm(0x3c3,  1, 1)
  1340.              || ioperm(0x3cd,  1, 1)
  1341.                )
  1342.                 err = 1;
  1343.  
  1344.             END_ROOT_PRIV;
  1345.  
  1346.             if (err)
  1347.                 return -1; /* can't get I/O permissions */
  1348.           }
  1349.           #endif
  1350.  
  1351.           #ifdef EMUNIX
  1352.  
  1353.             if (_portaccess(0x3B4,0x3DA))
  1354.                 { errno = EPERM; return -1; } /* can't get I/O permissions */
  1355.  
  1356.           #endif
  1357.  
  1358.             /* color or monochrome text emulation? */
  1359.             color_text = port_in(MIS_R) & 0x01;
  1360.  
  1361.             /* chose registers for color/monochrome emulation */
  1362.             if (color_text) {
  1363.                 CRT_I = CRT_IC;
  1364.                 CRT_D = CRT_DC;
  1365.                 IS1_R = IS1_RC;
  1366.             } else {
  1367.                 CRT_I = CRT_IM;
  1368.                 CRT_D = CRT_DM;
  1369.                 IS1_R = IS1_RM;
  1370.             }
  1371.  
  1372.             done = 1;
  1373.         }
  1374.  
  1375.     return 0;
  1376. }
  1377.  
  1378.  
  1379. # Returns 1 if an ET4000 card is present, else 0.
  1380.  
  1381. static int et4000_test (void)
  1382. {
  1383.     static int result = -1;
  1384.     uchar new, old, val;
  1385.     int  base;
  1386.  
  1387.     /* test already done? */
  1388.     if (result >= 0)
  1389.         return result;
  1390.  
  1391.     /* test for Tseng clues */
  1392.     old = port_in(0x3cd);
  1393.     port_out(0x55, 0x3cd);
  1394.     new = port_in(0x3cd);
  1395.     port_out(old, 0x3cd);
  1396.  
  1397.     /* return false if not Tseng */
  1398.     if (new != 0x55)
  1399.         return result = 0;
  1400.  
  1401.     /* test for ET4000 clues */
  1402.     if (port_in(0x3cc) & 1)
  1403.         base = 0x3d4;
  1404.     else
  1405.         base = 0x3b4;
  1406.     port_out(0x33, base);
  1407.     old = port_in(base+1);
  1408.     new = old ^ 0xf;
  1409.     port_out(new, base+1);
  1410.     val = port_in(base+1);
  1411.     port_out(old, base+1);
  1412.  
  1413.     /* return true if ET4000 */
  1414.     return result = (val == new);
  1415. }
  1416.  
  1417.  
  1418. static void et4000_save_regs (uchar regs[])
  1419. {
  1420.     int i;
  1421.  
  1422.     /* save extended CRT registers */
  1423.     for (i = 0; i < 6; i++) {
  1424.          port_out(0x32+i, CRT_I);
  1425.          regs[EXT+i] = port_in(CRT_D);
  1426.     }
  1427.  
  1428.     /* save extended sequencer register */
  1429.     port_out(7, SEQ_I);
  1430.     regs[EXT+6] = port_in(SEQ_D);
  1431.  
  1432.     /* save some other ET4000 specific registers */
  1433.     regs[EXT+7] = port_in(0x3c3);
  1434.     regs[EXT+8] = port_in(0x3cd);
  1435.  
  1436.     /* save extended attribute register */
  1437.     port_in(IS1_R);    /* reset flip flop */
  1438.     port_out(0x16, ATT_IW);
  1439.     regs[EXT+9] = port_in(ATT_R);
  1440. }
  1441.  
  1442.  
  1443. static void et4000_set_regs (uchar regs[])
  1444. {
  1445.     int i;
  1446.  
  1447.     /* write some ET4000 specific registers */
  1448.     port_out(regs[EXT+7], 0x3c3);
  1449.     port_out(regs[EXT+8], 0x3cd);
  1450.  
  1451.     /* write extended sequencer register */
  1452.     port_out(7, SEQ_I);
  1453.     port_out(regs[EXT+6], SEQ_D);
  1454.  
  1455.     /* write extended CRT registers */
  1456.     for (i = 0; i < 6; i++) {
  1457.          port_out(0x32+i, CRT_I);
  1458.          port_out(regs[EXT+i], CRT_D);
  1459.     }
  1460.  
  1461.     /* write extended attribute register */
  1462.     port_in(IS1_R);    /* reset flip flop */
  1463.     port_out(0x16, ATT_IW);
  1464.     port_out(regs[EXT+9], ATT_IW);
  1465. }
  1466.  
  1467.  
  1468. static void save_regs (uchar regs[])
  1469. {
  1470.     int i;
  1471.  
  1472.     /* save VGA registers */
  1473.     for (i = 0; i < CRT_C; i++) {
  1474.          port_out(i, CRT_I);
  1475.          regs[CRT+i] = port_in(CRT_D);
  1476.     }
  1477.     for (i = 0; i < ATT_C; i++) {
  1478.          port_in(IS1_R);
  1479.          port_out(i, ATT_IW);
  1480.          regs[ATT+i] = port_in(ATT_R);
  1481.     }
  1482.     for (i = 0; i < GRA_C; i++) {
  1483.          port_out(i, GRA_I);
  1484.          regs[GRA+i] = port_in(GRA_D);
  1485.     }
  1486.     for (i = 0; i < SEQ_C; i++) {
  1487.          port_out(i, SEQ_I);
  1488.          regs[SEQ+i] = port_in(SEQ_D);
  1489.     }
  1490.     regs[MIS] = port_in(MIS_R);
  1491.  
  1492.     if (et4000)
  1493.         et4000_save_regs(regs);
  1494. }
  1495.  
  1496.  
  1497. static void set_regs (uchar regs[], int mode)
  1498. {
  1499.     int i;
  1500.  
  1501.     /* disable video */
  1502.     port_in(IS1_R);
  1503.     port_out(0x00, ATT_IW);
  1504.  
  1505.     /* update misc output register */
  1506.     port_out(regs[MIS], MIS_W);
  1507.  
  1508.     /* synchronous reset on */
  1509.     port_out(0x00,SEQ_I);
  1510.     port_out(0x01,SEQ_D);
  1511.  
  1512.     /* write sequencer registers */
  1513.     for (i = 1; i < SEQ_C; i++) {
  1514.         port_out(i, SEQ_I);
  1515.         port_out(regs[SEQ+i], SEQ_D);
  1516.     }
  1517.  
  1518.     /* synchronous reset off */
  1519.     port_out(0x00, SEQ_I);
  1520.     port_out(0x03, SEQ_D);
  1521.  
  1522.     /* deprotect CRT registers 0-7 */
  1523.     port_out(0x11, CRT_I);
  1524.     port_out(port_in(CRT_D)&0x7F, CRT_D);
  1525.  
  1526.     /* write CRT registers */
  1527.     for (i = 0; i < CRT_C; i++) {
  1528.         port_out(i, CRT_I);
  1529.         port_out(regs[CRT+i], CRT_D);
  1530.     }
  1531.  
  1532.     /* write graphics controller registers */
  1533.     for (i = 0; i < GRA_C; i++) {
  1534.         port_out(i, GRA_I);
  1535.         port_out(regs[GRA+i], GRA_D);
  1536.     }
  1537.  
  1538.     /* write attribute controller registers */
  1539.     for (i = 0; i < ATT_C; i++) {
  1540.         port_in(IS1_R);   /* reset flip-flop */
  1541.         port_out(i, ATT_IW);
  1542.         port_out(regs[ATT+i],ATT_IW);
  1543.     }
  1544.  
  1545.     if (et4000)
  1546.         if (mode == G640x480x256 || mode == G800x600x256 || mode == G1024x768x256)
  1547.             et4000_set_regs(regs);
  1548. }
  1549.  
  1550.  
  1551. static void vga_setpalette (int index, int red, int green, int blue)
  1552. {
  1553.     int i;
  1554.  
  1555.     /* select palette register */
  1556.     port_out(index, PEL_IW);
  1557.  
  1558.     /* write RGB components */
  1559.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1560.     port_out(red, PEL_D);
  1561.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1562.     port_out(green, PEL_D);
  1563.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1564.     port_out(blue, PEL_D);
  1565. }
  1566.  
  1567.  
  1568. static void vga_getpalette (int index, int *red, int *green, int *blue)
  1569. {
  1570.     int i;
  1571.  
  1572.     /* select palette register */
  1573.     port_out(index, PEL_IR);
  1574.  
  1575.     /* read RGB components */
  1576.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1577.     *red = (int) port_in(PEL_D);
  1578.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1579.     *green = (int) port_in(PEL_D);
  1580.     for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1581.     *blue = (int) port_in(PEL_D);
  1582. }
  1583.  
  1584. #if 0
  1585.  
  1586. static void vga_setpalvec (int start, int num, int *pal)
  1587. {
  1588.     int i, j;
  1589.  
  1590.     /* select palette register */
  1591.     port_out(start, PEL_IW);
  1592.  
  1593.     for(j = 0; j < num; j++) {
  1594.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1595.         port_out(*(pal++), PEL_D);
  1596.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1597.         port_out(*(pal++), PEL_D);
  1598.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1599.         port_out(*(pal++), PEL_D);
  1600.     }
  1601. }
  1602.  
  1603.  
  1604. static void vga_getpalvec (int start, int num, int *pal)
  1605. {
  1606.     int i, j;
  1607.  
  1608.     /* select palette register */
  1609.     port_out(start, PEL_IR);
  1610.  
  1611.     for(j = 0; j < num; j++) {
  1612.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1613.         *(pal++) = (int) port_in(PEL_D);
  1614.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1615.         *(pal++) = (int) port_in(PEL_D);
  1616.         for(i = 0; i < 10; i++) ;   /* delay (minimum 240ns) */
  1617.         *(pal++) = (int) port_in(PEL_D);
  1618.     }
  1619. }
  1620.  
  1621. #endif
  1622.  
  1623. void vga_setcolor (int color)
  1624. {
  1625.     switch (cur_mode) {
  1626.         case G320x200x16:
  1627.         case G640x200x16:
  1628.         case G640x350x16:
  1629.         case G640x480x16:
  1630.             /* update set/reset register */
  1631.             port_out(0x00, GRA_I );
  1632.             port_out(color, GRA_D );
  1633.             break;
  1634.         case G640x480x2:
  1635.             if (color != 0)
  1636.                 color = 15;
  1637.             /* update set/reset register */
  1638.             port_out(0x00, GRA_I );
  1639.             port_out(color, GRA_D );
  1640.             break;
  1641.         case G320x200x256:
  1642.         case G320x240x256:
  1643.         case G320x400x256:
  1644.         case G360x480x256:
  1645.         case G640x480x256:
  1646.         case G800x600x256:
  1647.         case G1024x768x256:
  1648.             cur_color = color;
  1649.             break;
  1650.     }
  1651. }
  1652.  
  1653.  
  1654. void vga_screenoff()
  1655. {
  1656.     /* turn off screen for faster VGA memory access */
  1657.     port_out(0x01, SEQ_I);
  1658.     port_out(port_in(SEQ_D)|0x20, SEQ_D);
  1659. }
  1660.  
  1661.  
  1662. void vga_screenon()
  1663. {
  1664.     /* turn screen back on */
  1665.     port_out(0x01, SEQ_I);
  1666.     port_out(port_in(SEQ_D)&0xDF, SEQ_D);
  1667. }
  1668.  
  1669.  
  1670. void vga_clear()
  1671. {
  1672.     int i, j;
  1673.  
  1674.     vga_screenoff();
  1675.  
  1676.     switch (cur_mode) {
  1677.         case G320x200x16:
  1678.         case G640x200x16:
  1679.         case G640x350x16:
  1680.         case G640x480x16:
  1681.         case G640x480x2:
  1682.             vga_setcolor(0);
  1683.  
  1684.             /* write to all bits */
  1685.             port_out(0x08, GRA_I );
  1686.             port_out(0xFF, GRA_D );
  1687.  
  1688.             /* write dummy values to clear video memory */
  1689.             for(i = 0; i < 16; i++)
  1690.                 memcpy(graph_mem + i*NULL_SIZE, null_buf, NULL_SIZE);
  1691.  
  1692.             break;
  1693.         case G320x200x256:
  1694.         case G320x240x256:
  1695.         case G320x400x256:
  1696.         case G360x480x256:
  1697.             /* write to all planes */
  1698.             port_out(0x02, SEQ_I );
  1699.             port_out(0x0F, SEQ_D );
  1700.  
  1701.             /* clear video memory */
  1702.             for(i = 0; i < 16; i++)
  1703.                 memcpy(graph_mem + i*NULL_SIZE, null_buf, NULL_SIZE);
  1704.  
  1705.             break;
  1706.         case G640x480x256:
  1707.         case G800x600x256:
  1708.         case G1024x768x256:
  1709.             for(i = 0; i < 16; i++) {
  1710.                 /* select segment */
  1711.                 port_out(i, SEG_SELECT);
  1712.  
  1713.                 /* clear video memory */
  1714.                 for(j = 0; j < 16; j++)
  1715.                     memcpy(graph_mem + j*NULL_SIZE, null_buf, NULL_SIZE);
  1716.             }
  1717.             break;
  1718.     }
  1719.  
  1720.     vga_setcolor(15);
  1721.  
  1722.     vga_screenon();
  1723. }
  1724.  
  1725.  
  1726. /* set cur_mode to TEXT */
  1727. static void set_textmode (void)
  1728. {
  1729.     int i;
  1730.  
  1731.     /* disable video */
  1732.     port_in(IS1_R);
  1733.     port_out(0x00, ATT_IW);
  1734.  
  1735.     if (et4000 && cur_mode == G1024x768x256)
  1736.         set_regs(g640x480x256_regs, G640x480x256);
  1737.  
  1738.     cur_mode = TEXT;
  1739.  
  1740.     /* restore font data - first select a 16 color graphics mode */
  1741.     set_regs(g640x480x16_regs, G640x480x16);
  1742.  
  1743.     /* disable Set/Reset Register */
  1744.     port_out(0x01, GRA_I );
  1745.     port_out(0x00, GRA_D );
  1746.  
  1747.     /* restore font data in plane 2 - necessary for all VGA's */
  1748.     port_out(0x02, SEQ_I );
  1749.     port_out(0x04, SEQ_D );
  1750.     memcpy(graph_mem, font_buf1, FONT_SIZE);
  1751.  
  1752.     /* restore font data in plane 3 - necessary for Trident VGA's */
  1753.     port_out(0x02, SEQ_I );
  1754.     port_out(0x08, SEQ_D );
  1755.     memcpy(graph_mem, font_buf2, FONT_SIZE);
  1756.  
  1757.     /* change register adresses if monochrome text mode */
  1758.     if (!color_text) {
  1759.         CRT_I = CRT_IM;
  1760.         CRT_D = CRT_DM;
  1761.         IS1_R = IS1_RM;
  1762.         port_out(port_in(MIS_R)&0xFE, MIS_W);
  1763.     }
  1764.  
  1765.     /* restore saved palette */
  1766.     for(i = 0; i < 256; i++)
  1767.         vga_setpalette(i, text_red[i], text_green[i], text_blue[i]);
  1768.  
  1769.     /* restore text mode VGA registers */
  1770.     set_regs(text_regs, TEXT);
  1771.  
  1772.     /* enable video */
  1773.     port_in(IS1_R);
  1774.     port_out(0x20, ATT_IW);
  1775.  
  1776.     #ifdef UNIX
  1777.     /* enable text output - restores the screen contents */
  1778.     ioctl(tty0_fd, KDSETMODE, KD_TEXT);
  1779.     #endif
  1780.     #ifdef EMUNIX
  1781.     kd_text();
  1782.     #endif
  1783.  
  1784.     /* restore text mode termio */
  1785.     set_textmode_signals();
  1786. }
  1787.  
  1788.  
  1789. /* set cur_mode to mode != TEXT, maybe clearing the screen */
  1790. static void set_graphmode (int mode, int clear)
  1791. {
  1792.     int i;
  1793.  
  1794.     #ifdef UNIX
  1795.     /* disable text output */
  1796.     ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
  1797.     #endif
  1798.     #ifdef EMUNIX
  1799.     kd_graphics();
  1800.     #endif
  1801.  
  1802.     /* disable video */
  1803.     port_in(IS1_R);
  1804.     port_out(0x00, ATT_IW);
  1805.  
  1806.     if (et4000 && cur_mode == G1024x768x256)
  1807.         set_regs(g640x480x256_regs, G640x480x256);
  1808.  
  1809.     cur_mode = mode;
  1810.  
  1811.     /* shift to color emulation */
  1812.     CRT_I = CRT_IC;
  1813.     CRT_D = CRT_DC;
  1814.     IS1_R = IS1_RC;
  1815.     port_out(port_in(MIS_R)|0x01, MIS_W);
  1816.  
  1817.     switch (mode) {
  1818.         case G320x200x16:
  1819.             set_regs(g320x200x16_regs, G320x200x16);
  1820.             cur_info = g320x200x16_info;
  1821.             break;
  1822.         case G640x200x16:
  1823.             set_regs(g640x200x16_regs, G640x200x16);
  1824.             cur_info = g640x200x16_info;
  1825.             break;
  1826.         case G640x350x16:
  1827.             set_regs(g640x350x16_regs, G640x350x16);
  1828.             cur_info = g640x350x16_info;
  1829.             break;
  1830.         case G640x480x16:
  1831.             set_regs(g640x480x16_regs, G640x480x16);
  1832.             cur_info = g640x480x16_info;
  1833.             break;
  1834.         case G320x200x256:
  1835.             set_regs(g320x200x256_regs, G320x200x256);
  1836.             cur_info = g320x200x256_info;
  1837.             break;
  1838.         case G320x240x256:
  1839.             set_regs(g320x240x256_regs, G320x240x256);
  1840.             cur_info = g320x240x256_info;
  1841.             break;
  1842.         case G320x400x256:
  1843.             set_regs(g320x400x256_regs, G320x400x256);
  1844.             cur_info = g320x400x256_info;
  1845.             break;
  1846.         case G360x480x256:
  1847.             set_regs(g360x480x256_regs, G360x480x256);
  1848.             cur_info = g360x480x256_info;
  1849.             break;
  1850.         case G640x480x2:
  1851.             set_regs(g640x480x2_regs, G640x480x2);
  1852.             cur_info = g640x480x2_info;
  1853.             break;
  1854.         case G640x480x256:
  1855.             set_regs(g640x480x256_regs, G640x480x256);
  1856.             cur_info = g640x480x256_info;
  1857.             break;
  1858.         case G800x600x256:
  1859.             set_regs(g800x600x256_regs, G800x600x256);
  1860.             cur_info = g800x600x256_info;
  1861.             break;
  1862.         case G1024x768x256:
  1863.             set_regs(g1024x768x256_regs, G1024x768x256);
  1864.             cur_info = g1024x768x256_info;
  1865.             break;
  1866.     }
  1867.     cur_clip.x1 = 0; cur_clip.x2 = cur_info.xdim-1;
  1868.     cur_clip.y1 = 0; cur_clip.y2 = cur_info.ydim-1;
  1869.  
  1870.     if (clear) {
  1871.         /* set default palette */
  1872.         for(i = 0; i < 256; i++)
  1873.             vga_setpalette(i, default_red[i],default_green[i],default_blue[i]);
  1874.  
  1875.         /* clear screen (sets current color to 15) */
  1876.         vga_clear();
  1877.     }
  1878.  
  1879.     /* enable video */
  1880.     port_in(IS1_R);
  1881.     port_out(0x20, ATT_IW);
  1882.  
  1883.     /* set graphics mode termio */
  1884.     set_graphmode_signals();
  1885. }
  1886.  
  1887.  
  1888. /* Global initialization. */
  1889. /* Only called once, by the first call to vga_hasmode() or vga_setmode(). */
  1890.  
  1891. static int initialize (void)
  1892. {
  1893.     int result;
  1894.     int i, j;
  1895.  
  1896.     disable_interrupts();
  1897.  
  1898.     if (get_perm())
  1899.         { asciz_out("VGAlib: can't get I/O permissions" CRLFstring);
  1900.           result = -1; goto done;
  1901.         }
  1902.  
  1903.     et4000 = et4000_test();
  1904.  
  1905.     if (et4000) {
  1906.         /* get access to extended registers */
  1907.         port_out(3, 0x3bf);
  1908.         if (port_in( 0x3cc ) & 1)
  1909.             port_out(0xa0, 0x3d8);
  1910.         else
  1911.             port_out(0xa0, 0x3b8);
  1912.     }
  1913.  
  1914.     #ifdef EMUNIX
  1915.  
  1916.     /* enquire text mode parameters */
  1917.     get_text_info();
  1918.  
  1919.     /* allocate memory for saved text data */
  1920.     if ((text_buf = malloc(2*text_size)) == NULL)
  1921.         { asciz_out("VGAlib: not enough memory" CRLFstring);
  1922.           errno = ENOMEM; return -1;
  1923.         }
  1924.  
  1925.     #endif
  1926.  
  1927.     /* allocate memory for saved graphics data */
  1928.     if ((graph_buf = malloc(4*GRAPH_SIZE)) == NULL)
  1929.         { asciz_out("VGAlib: not enough memory" CRLFstring);
  1930.           errno = ENOMEM; return -1;
  1931.         }
  1932.  
  1933.     #ifdef UNIX
  1934.  
  1935.     {   int mem_fd;
  1936.         uchar* mem_area;
  1937.  
  1938.         BEGIN_ROOT_PRIV;
  1939.  
  1940.         /* open /dev/tty0 - current virtual console */
  1941.         if ((tty0_fd = open("/dev/console", O_RDONLY) ) < 0)
  1942.             if ((tty0_fd = open("/dev/tty0", O_RDONLY) ) < 0)
  1943.                 { END_ROOT_PRIV;
  1944.                   free(graph_buf);
  1945.                   asciz_out("VGAlib: can't open /dev/console" CRLFstring);
  1946.                   result = -1; goto done;
  1947.                 }
  1948.  
  1949.         /* open /dev/mem */
  1950.         if ((mem_fd = open("/dev/mem", O_RDWR) ) < 0)
  1951.             { END_ROOT_PRIV;
  1952.               close(tty0_fd); free(graph_buf);
  1953.               asciz_out("VGAlib: can't open /dev/mem" CRLFstring);
  1954.               result = -1; goto done;
  1955.             }
  1956.  
  1957.         END_ROOT_PRIV;
  1958.  
  1959.         /* mmap graphics memory */
  1960.         if ((mem_area = malloc(GRAPH_SIZE + getpagesize()-1)) == NULL)
  1961.             { close(tty0_fd); close(mem_fd); free(graph_buf);
  1962.               asciz_out("VGAlib: not enough memory" CRLFstring);
  1963.               errno = ENOMEM; result = -1; goto done;
  1964.             }
  1965.         graph_mem = mem_area + ((-(unsigned long)mem_area) & (getpagesize()-1));
  1966.         graph_mem = (uchar *) mmap((CADDR_T)graph_mem, GRAPH_SIZE,
  1967.                                    PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED,
  1968.                                    mem_fd, GRAPH_BASE);
  1969.         if (graph_mem == (uchar *)(-1))
  1970.             { close(tty0_fd); close(mem_fd); free(mem_area); free(graph_buf);
  1971.               asciz_out("VGAlib: couldn't mmap graphics memory" CRLFstring);
  1972.               result = -1; goto done;
  1973.             }
  1974.     }
  1975.  
  1976.     #endif
  1977.  
  1978.     #ifdef EMUNIX
  1979.  
  1980.     text_mem = memaccess (text_phys_mem, text_phys_mem+2*text_size-1, 1);
  1981.     if (text_mem == NULL)
  1982.         { asciz_out("VGAlib: couldn't get access to text memory" CRLFstring);
  1983.           errno = EINVAL; result = -1; goto done;
  1984.         }
  1985.  
  1986.     graph_mem = memaccess (GRAPH_BASE, GRAPH_BASE+GRAPH_SIZE-1, 1);
  1987.     if (graph_mem == NULL)
  1988.         { asciz_out("VGAlib: couldn't get access to graphics memory" CRLFstring);
  1989.           errno = EINVAL; result = -1; goto done;
  1990.         }
  1991.  
  1992.     #endif
  1993.  
  1994.     /* Here's the point of no return. */
  1995.  
  1996.     #ifdef UNIX
  1997.     /* disable text output to console */
  1998.     ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
  1999.     #endif
  2000.  
  2001.     /* disable video */
  2002.     port_in(IS1_R);
  2003.     port_out(0x00, ATT_IW);
  2004.  
  2005.     save_regs(text_regs);
  2006.  
  2007.     /* save text mode palette - first select palette index 0 */
  2008.     port_out(0, PEL_IR);
  2009.  
  2010.     /* read RGB components - index is autoincremented */
  2011.     for(i = 0; i < 256; i++) {
  2012.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2013.         text_red[i] = port_in(PEL_D);
  2014.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2015.         text_green[i] = port_in(PEL_D);
  2016.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2017.         text_blue[i] = port_in(PEL_D);
  2018.     }
  2019.  
  2020.     /* shift to color emulation */
  2021.     CRT_I = CRT_IC;
  2022.     CRT_D = CRT_DC;
  2023.     IS1_R = IS1_RC;
  2024.     port_out(port_in(MIS_R)|0x01, MIS_W);
  2025.  
  2026.     /* save font data - first select a 16 color graphics mode */
  2027.     set_regs(g640x480x16_regs, G640x480x16);
  2028.  
  2029.     /* save font data in plane 2 */
  2030.     port_out(0x04, GRA_I);
  2031.     port_out(0x02, GRA_D);
  2032.     memcpy(font_buf1, graph_mem, FONT_SIZE);
  2033.  
  2034.     /* save font data in plane 3 */
  2035.     port_out(0x04, GRA_I);
  2036.     port_out(0x03, GRA_D);
  2037.     memcpy(font_buf2, graph_mem, FONT_SIZE);
  2038.  
  2039.     /* enable video */
  2040.     port_in(IS1_R);
  2041.     port_out(0x20, ATT_IW);
  2042.  
  2043.     /* initialize buffer used when clearing in 256 color modes */
  2044.     for(i = 0; i < NULL_SIZE; i++)
  2045.         null_buf[i] = 0;
  2046.  
  2047.     /* we have modified the VGA registers -- back to text mode for now */
  2048.     set_textmode();
  2049.  
  2050.     initialized = 1;
  2051.  
  2052.     result = 0;
  2053.  
  2054.     done:
  2055.     enable_interrupts();
  2056.  
  2057.     return result;
  2058. }
  2059.  
  2060.  
  2061. int vga_hasmode (int mode)
  2062. {
  2063.     switch (mode) {
  2064.         case TEXT:
  2065.             return 1;
  2066.         case G320x200x16:
  2067.         case G640x200x16:
  2068.         case G640x350x16:
  2069.         case G640x480x16:
  2070.         case G640x480x2:
  2071.         case G320x200x256:
  2072.         case G320x240x256:
  2073.         case G320x400x256:
  2074.         case G360x480x256:
  2075.             if (!initialized)
  2076.                 if (initialize())
  2077.                     return 0;
  2078.             return 1;
  2079.         case G640x480x256:
  2080.         case G800x600x256:
  2081.         case G1024x768x256:
  2082.             if (!initialized)
  2083.                 if (initialize())
  2084.                     return 0;
  2085.             return et4000;
  2086.         default:
  2087.             return 0;
  2088.     }
  2089. }
  2090.  
  2091. int vga_setmode (int mode)
  2092. {
  2093.     if (!initialized)
  2094.         if (initialize())
  2095.             return -1;
  2096.  
  2097.     disable_interrupts();
  2098.  
  2099.     if (mode == TEXT)
  2100.         set_textmode();
  2101.     else
  2102.         set_graphmode(mode,1);
  2103.  
  2104.     enable_interrupts();
  2105.  
  2106.     return 0;
  2107. }
  2108.  
  2109.  
  2110. # We do `lazy switching' between text mode and graphics mode.
  2111. # This switching doesn't lose screen's contents. It is therefore also called
  2112. # `flipping'.
  2113. # flip_mode is the mode of the "screen behind the scenes".
  2114. # At least one of cur_mode and flip_mode is TEXT.
  2115.  
  2116. void switch_text_mode (void)
  2117. {
  2118.     int i, j;
  2119.  
  2120.     if (cur_mode == TEXT)
  2121.         return;
  2122.  
  2123.     /* cur_mode != TEXT, so flip_mode == TEXT,
  2124.        and initialize() has already been called. */
  2125.  
  2126.     disable_interrupts();
  2127.  
  2128.     /* disable video */
  2129.     port_in(IS1_R);
  2130.     port_out(0x00, ATT_IW);
  2131.  
  2132.     /* save all four planes - first select a 16 color graphics mode */
  2133.     set_regs(g640x480x16_regs, G640x480x16);
  2134.  
  2135.     for(i = 0; i < 4; i++) {
  2136.         /* save plane i */
  2137.         port_out(0x04, GRA_I);
  2138.         port_out(   i, GRA_D);
  2139.         memcpy(graph_buf + i*GRAPH_SIZE, graph_mem, GRAPH_SIZE);
  2140.     }
  2141.  
  2142.     /* save graphics mode palette - first select palette index 0 */
  2143.     port_out(0, PEL_IR);
  2144.  
  2145.     /* read RGB components - index is autoincremented */
  2146.     for(i = 0; i < 256; i++) {
  2147.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2148.         graph_red[i] = port_in(PEL_D);
  2149.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2150.         graph_green[i] = port_in(PEL_D);
  2151.         for(j = 0; j < 10; j++) ;   /* delay (minimum 240ns) */
  2152.         graph_blue[i] = port_in(PEL_D);
  2153.     }
  2154.  
  2155.     flip_mode = cur_mode;
  2156.  
  2157.     set_textmode();
  2158.  
  2159.     enable_interrupts();
  2160. }
  2161.  
  2162. void switch_graphics_mode (void)
  2163. {
  2164.     int i;
  2165.  
  2166.     if (flip_mode == TEXT)
  2167.         return;
  2168.  
  2169.     /* flip_mode != TEXT, so cur_mode == TEXT,
  2170.        and initialize() has already been called. */
  2171.  
  2172.     disable_interrupts();
  2173.  
  2174.     #ifdef UNIX
  2175.     /* disable text output */
  2176.     ioctl(tty0_fd, KDSETMODE, KD_GRAPHICS);
  2177.     #endif
  2178.     #ifdef EMUNIX
  2179.     kd_graphics();
  2180.     #endif
  2181.  
  2182.     /* disable video */
  2183.     port_in(IS1_R);
  2184.     port_out(0x00, ATT_IW);
  2185.  
  2186.     /* restore all four planes - first select a 16 color graphics mode */
  2187.     set_regs(g640x480x16_regs, G640x480x16);
  2188.  
  2189.     /* disable Set/Reset Register */
  2190.     port_out(0x01, GRA_I );
  2191.     port_out(0x00, GRA_D );
  2192.  
  2193.     for(i = 0; i < 4; i++) {
  2194.         /* restore plane i */
  2195.         port_out(0x02, SEQ_I );
  2196.         port_out(1<<i, SEQ_D );
  2197.         memcpy(graph_mem, graph_buf + i*GRAPH_SIZE, GRAPH_SIZE);
  2198.     }
  2199.  
  2200.     /* restore saved palette */
  2201.     for(i = 0; i < 256; i++)
  2202.         vga_setpalette(i, graph_red[i], graph_green[i], graph_blue[i]);
  2203.  
  2204.     set_graphmode(flip_mode,0);
  2205.  
  2206.     flip_mode = TEXT;
  2207.  
  2208.     enable_interrupts();
  2209. }
  2210.  
  2211.  
  2212. void vga_drawpixel (int x, int y)
  2213. {
  2214.     unsigned long offset;
  2215.  
  2216.     switch (cur_mode) {
  2217.         case G320x200x16:
  2218.         case G640x200x16:
  2219.         case G640x350x16:
  2220.         case G640x480x16:
  2221.         case G640x480x2:
  2222.             /* select bit */
  2223.             port_out(8, GRA_I);
  2224.             port_out(0x80 >> (x & 7), GRA_D);
  2225.  
  2226.             /* read into latch and write dummy back */
  2227.             offset = y*cur_info.xbytes + (x>>3);
  2228.             graph_mem[offset] = graph_mem[offset];
  2229.             break;
  2230.         case G320x200x256:
  2231.             /* write color to pixel */
  2232.             graph_mem[y*320 + x] = cur_color;
  2233.             break;
  2234.         case G320x240x256:
  2235.         case G320x400x256:
  2236.         case G360x480x256:
  2237.             /* select plane */
  2238.             port_out(0x02, SEQ_I);
  2239.             port_out(1 << (x & 3), SEQ_D);
  2240.  
  2241.             /* write color to pixel */
  2242.             graph_mem[y*cur_info.xbytes + (x>>2)] = cur_color;
  2243.             break;
  2244.         case G640x480x256:
  2245.         case G800x600x256:
  2246.         case G1024x768x256:
  2247.             offset = y*cur_info.xbytes+x;
  2248.  
  2249.             /* select segment */
  2250.             port_out(offset >> 16, SEG_SELECT);
  2251.  
  2252.             /* write color to pixel */
  2253.             graph_mem[offset & 0xFFFF] = cur_color;
  2254.             break;
  2255.     }
  2256. }
  2257.  
  2258.  
  2259. /* Get pixel's color. */
  2260. int vga_getpixel (int x, int y)
  2261. {
  2262.     unsigned long offset;
  2263.  
  2264.     switch (cur_mode) {
  2265.         case G320x200x16:
  2266.         case G640x200x16:
  2267.         case G640x350x16:
  2268.         case G640x480x16:
  2269.         case G640x480x2:
  2270.             # Not yet tested!!
  2271.             { int i;
  2272.               int color = 0;
  2273.               uchar mask = 0x80 >> (x & 7);
  2274.               offset = y*cur_info.xbytes + (x>>3);
  2275.               for(i = 0; i < 4; i++) {
  2276.                   /* select plane i */
  2277.                   port_out(0x04, GRA_I);
  2278.                   port_out(   i, GRA_D);
  2279.                   if (graph_mem[offset] & mask)
  2280.                       color |= (1<<i);
  2281.               }
  2282.               return color;
  2283.             }
  2284.         case G320x200x256:
  2285.             /* get pixel color */
  2286.             return graph_mem[y*320 + x];
  2287.         case G320x240x256:
  2288.         case G320x400x256:
  2289.         case G360x480x256:
  2290.             /* select plane */
  2291.             port_out(0x02, SEQ_I);
  2292.             port_out(1 << (x & 3), SEQ_D);
  2293.  
  2294.             /* get pixel color */
  2295.             return graph_mem[y*cur_info.xbytes + (x>>2)];
  2296.         case G640x480x256:
  2297.         case G800x600x256:
  2298.         case G1024x768x256:
  2299.             offset = y*cur_info.xbytes+x;
  2300.  
  2301.             /* select segment */
  2302.             port_out(offset >> 16, SEG_SELECT);
  2303.  
  2304.             /* get pixel color */
  2305.             return graph_mem[offset & 0xFFFF];
  2306.         default:
  2307.             return -1;
  2308.     }
  2309. }
  2310.  
  2311. #if 0
  2312.  
  2313. /* display plane buffers (for fast scanline drawing) */
  2314. static uchar plane0[256];
  2315. static uchar plane1[256];
  2316. static uchar plane2[256];
  2317. static uchar plane3[256];
  2318.  
  2319. void vga_drawscansegment (uchar* colors, int x, int y, int length)
  2320. {
  2321.     /* both length and x must divide with 8 */
  2322.  
  2323.     switch (cur_mode) {
  2324.         case G320x200x16:
  2325.         case G640x200x16:
  2326.         case G640x350x16:
  2327.         case G640x480x16:
  2328.             {
  2329.                 int i, j, k, first, last;
  2330.                 union bits bytes;
  2331.                 uchar* address;
  2332.  
  2333.                 k = 0;
  2334.                 for(i = 0; i < length; i += 8) {
  2335.                     bytes.i = 0;
  2336.                     first = i;
  2337.                     last  = i+8;
  2338.                     for(j = first; j < last; j++)
  2339.                        bytes.i = (bytes.i<<1) | color16[colors[j]].i;
  2340.                     plane0[k]   = bytes.b.bit0;
  2341.                     plane1[k]   = bytes.b.bit1;
  2342.                     plane2[k]   = bytes.b.bit2;
  2343.                     plane3[k++] = bytes.b.bit3;
  2344.                 }
  2345.  
  2346.                 address = graph_mem + (y*cur_info.xdim+x)/8;
  2347.  
  2348.                 /* disable Set/Reset Register */
  2349.                 port_out(0x01, GRA_I );
  2350.                 port_out(0x00, GRA_D );
  2351.  
  2352.                 /* write to all bits */
  2353.                 port_out(0x08, GRA_I );
  2354.                 port_out(0xFF, GRA_D );
  2355.  
  2356.                 /* select map mask register */
  2357.                 port_out(0x02, SEQ_I );
  2358.  
  2359.                 /* write plane 0 */
  2360.                 port_out(0x01, SEQ_D );
  2361.                 memcpy(address, plane0, length/8);
  2362.  
  2363.                 /* write plane 1 */
  2364.                 port_out(0x02, SEQ_D );
  2365.                 memcpy(address, plane1, length/8);
  2366.  
  2367.                 /* write plane 2 */
  2368.                 port_out(0x04, SEQ_D );
  2369.                 memcpy(address, plane2, length/8);
  2370.  
  2371.                 /* write plane 3 */
  2372.                 port_out(0x08, SEQ_D );
  2373.                 memcpy(address, plane3, length/8);
  2374.  
  2375.                 /* restore map mask register */
  2376.                 port_out(0x0F, SEQ_D );
  2377.  
  2378.                 /* enable Set/Reset Register */
  2379.                 port_out(0x01, GRA_I );
  2380.                 port_out(0x0F, GRA_D );
  2381.             }
  2382.             break;
  2383.         case G640x480x2:
  2384.             {
  2385.                 /* disable Set/Reset Register */
  2386.                 port_out(0x01, GRA_I );
  2387.                 port_out(0x00, GRA_D );
  2388.  
  2389.                 /* write to all bits */
  2390.                 port_out(0x08, GRA_I );
  2391.                 port_out(0xFF, GRA_D );
  2392.  
  2393.                 /* write to all planes */
  2394.                 port_out(0x02, SEQ_I );
  2395.                 port_out(0x0F, SEQ_D );
  2396.  
  2397.                 memcpy(graph_mem + (y*cur_info.xdim+x)/8, colors, length);
  2398.  
  2399.                 /* restore map mask register */
  2400.                 port_out(0x0F, SEQ_D );
  2401.  
  2402.                 /* enable Set/Reset Register */
  2403.                 port_out(0x01, GRA_I );
  2404.                 port_out(0x0F, GRA_D );
  2405.             }
  2406.             break;
  2407.         case G320x200x256:
  2408.             /* linear addressing - easy and fast */
  2409.             memcpy(graph_mem + y*cur_info.xdim+x, colors, length);
  2410.             break;
  2411.         case G320x240x256:
  2412.         case G320x400x256:
  2413.         case G360x480x256:
  2414.             {
  2415.                 int first, last, offset, pixel, plane;
  2416.  
  2417.                 /* select map mask register */
  2418.                 port_out(0x02, SEQ_I);
  2419.  
  2420.                 for(plane = 0; plane < 4; plane++) {
  2421.                     /* select plane */
  2422.                     port_out(1 << plane, SEQ_D);
  2423.  
  2424.                     pixel = plane;
  2425.                     first = (y*cur_info.xdim+x)/4;
  2426.                     last  = (y*cur_info.xdim+x+length)/4;
  2427.                     for(offset = first; offset < last; offset++) {
  2428.                         graph_mem[offset] = colors[pixel];
  2429.                         pixel += 4;
  2430.                     }
  2431.                 }
  2432.             }
  2433.             break;
  2434.         case G640x480x256:
  2435.         case G800x600x256:
  2436.         case G1024x768x256:
  2437.             {
  2438.                 unsigned long offset;
  2439.                 int segment, free;
  2440.  
  2441.                 offset  = y*cur_info.xbytes+x;
  2442.                 segment = offset >> 16;
  2443.                 free    = ((segment+1)<<16)-offset;
  2444.  
  2445.                 if (free < length) {
  2446.                     port_out(segment, SEG_SELECT);
  2447.                     memcpy(graph_mem + (offset & 0xFFFF), colors, free);
  2448.                     port_out(segment+1, SEG_SELECT);
  2449.                     memcpy(graph_mem, colors+free, length-free);
  2450.                 } else {
  2451.                     port_out(segment, SEG_SELECT);
  2452.                     memcpy(graph_mem + (offset & 0xFFFF), colors, length);
  2453.                 }
  2454.  
  2455.             }
  2456.             break;
  2457.     }
  2458. }
  2459.  
  2460.  
  2461. void vga_drawscanline (int line, uchar* colors)
  2462. {
  2463.     if (cur_mode == G640x480x2)
  2464.         vga_drawscansegment(colors, 0, line, cur_info.xbytes); # xbytes = xdim/8
  2465.     else
  2466.         vga_drawscansegment(colors, 0, line, cur_info.xdim);
  2467. }
  2468.  
  2469.  
  2470. void vga_drawbox (int x1, int y1, int x2, int y2)
  2471. {
  2472.     /* we may assume 0 <= x1 <= x2 and 0 <= y1 <= y2 */
  2473.     int x1_8 = round_up((unsigned int) x1, 8);
  2474.     int x2_8 = round_down((unsigned int) (x2+1), 8);
  2475.     if (x1_8 < x2_8)
  2476.       { unsigned int scansegment_length = x2_8 - x1_8;
  2477.         if (cur_mode == G640x480x2) scansegment_length = scansegment_length/8;
  2478.        {uchar colors[scansegment_length];
  2479.         { int i;
  2480.           int color = cur_color;
  2481.           if (cur_mode == G640x480x2) color = (color==0 ? 0x00 : 0xFF);
  2482.           for (i=0; i<scansegment_length; i++)
  2483.               colors[i] = color;
  2484.         }
  2485.         { int x, y;
  2486.           for (y = y1; y <= y2; y++) {
  2487.               for (x = x1; x < x1_8; x++)
  2488.                   vga_drawpixel(x, y);
  2489.               vga_drawscansegment(colors,x1_8,y,scansegment_length);
  2490.               for (x = x2_8; x <= x2; x++)
  2491.                   vga_drawpixel(x, y);
  2492.         } }
  2493.       }}
  2494.       else
  2495.       { int x, y;
  2496.         for (y = y1; y <= y2; y++)
  2497.             for (x = x1; x <= x2; x++)
  2498.                 vga_drawpixel(x, y);
  2499.       }
  2500. }
  2501.  
  2502. # Leider gehen damit die 16-Farben-Modi nicht.
  2503. # Test:
  2504. # (progn
  2505. #   (graph-init 320 200 16) bzw.
  2506. #   (graph-init 640 200 16) bzw.
  2507. #   (graph-init 640 350 16) bzw.
  2508. #   (graph-init 640 480 16)
  2509. #   (graph-clear)
  2510. #   (graph-clear 10)
  2511. #   (graph-box 17 100 54 130 14)
  2512. #   (sleep 2)
  2513. # )
  2514.  
  2515. #endif
  2516.  
  2517. void vga_drawhline (int x1, int x2, int y)
  2518. {
  2519.     /* we may assume 0 <= x1 <= x2 */
  2520.  
  2521.     switch (cur_mode) {
  2522.         case G320x200x16:
  2523.         case G640x200x16:
  2524.         case G640x350x16:
  2525.         case G640x480x16:
  2526.         case G640x480x2:
  2527.           { volatile uchar* p1 = &graph_mem[y*cur_info.xbytes + (x1>>3)];
  2528.             volatile uchar* p2 = &graph_mem[y*cur_info.xbytes + (x2>>3)];
  2529.             volatile uchar* p;
  2530.  
  2531.             x1 &= 7;
  2532.             x2 &= 7;
  2533.             if (p1 == p2)
  2534.               { /* select bits */
  2535.                 port_out(8, GRA_I);
  2536.                 port_out((0x100 >> x1) - (0x80 >> x2), GRA_D);
  2537.                 /* read into latch and write dummy back */
  2538.                 *p2 = *p2;
  2539.               }
  2540.               else # p1 < p2
  2541.               { p = p1;
  2542.                 /* select bits 7-x1..0 */
  2543.                 port_out(8, GRA_I);
  2544.                 port_out((0x100 >> x1) - 1, GRA_D);
  2545.                 /* read into latch and write dummy back */
  2546.                 *p = *p;
  2547.                 if (++p < p2)
  2548.                   { /* select bits 7..0 */
  2549.                     port_out(8, GRA_I);
  2550.                     port_out(0x100 - 1, GRA_D);
  2551.                     do { /* read into latch and write dummy back */
  2552.                          *p = *p;
  2553.                        }
  2554.                        while (++p < p2);
  2555.                   }
  2556.                 /* select bits 7..7-x2 */
  2557.                 port_out(8, GRA_I);
  2558.                 port_out(0x100 - (0x80 >> x2), GRA_D);
  2559.                 /* read into latch and write dummy back */
  2560.                 *p = *p;
  2561.               }
  2562.           }
  2563.           break;
  2564.         case G320x200x256:
  2565.           { volatile uchar* p1 = &graph_mem[y*320 + x1];
  2566.             volatile uchar* p2 = &graph_mem[y*320 + x2];
  2567.             volatile uchar* p;
  2568.  
  2569.             /* write color to pixels */
  2570.             for (p=p1; p<=p2; p++)
  2571.                 *p = cur_color;
  2572.           }
  2573.           break;
  2574.         case G320x240x256:
  2575.         case G320x400x256:
  2576.         case G360x480x256:
  2577.           { volatile uchar* p1 = &graph_mem[y*cur_info.xbytes + (x1>>2)];
  2578.             volatile uchar* p2 = &graph_mem[y*cur_info.xbytes + (x2>>2)];
  2579.             volatile uchar* p;
  2580.             int i;
  2581.  
  2582.             x1 &= 3;
  2583.             x2 &= 3;
  2584.             if (p1 == p2)
  2585.                 for (i = x1; i <= x2; i++) {
  2586.                     /* select plane */
  2587.                     port_out(0x02, SEQ_I);
  2588.                     port_out(1 << i, SEQ_D);
  2589.  
  2590.                     /* write color to pixel */
  2591.                     *p2 = cur_color;
  2592.                 }
  2593.               else # p1 < p2
  2594.                 for (i = 0; i < 4; i++) {
  2595.                     /* select plane */
  2596.                     port_out(0x02, SEQ_I);
  2597.                     port_out(1 << i, SEQ_D);
  2598.  
  2599.                     /* write color to pixels */
  2600.                     p = p1;
  2601.                     if (i >= x1)
  2602.                         *p = cur_color;
  2603.                     while (++p < p2)
  2604.                         *p = cur_color;
  2605.                     if (i <= x2)
  2606.                         *p = cur_color;
  2607.                 }
  2608.           }
  2609.           break;
  2610.         case G640x480x256:
  2611.         case G800x600x256:
  2612.         case G1024x768x256:
  2613.           { unsigned long offset1 = y*cur_info.xbytes + x1;
  2614.             unsigned long offset2 = y*cur_info.xbytes + x2;
  2615.             volatile uchar* p;
  2616.             volatile uchar* p2;
  2617.  
  2618.             if ((offset1 >> 16) == (offset2 >> 16))
  2619.               { /* select segment */
  2620.                 port_out(offset1 >> 16, SEG_SELECT);
  2621.                 /* write color to pixels */
  2622.                 offset1 &= 0xFFFF; offset2 &= 0xFFFF;
  2623.                 for (p = &graph_mem[offset1], p2 = &graph_mem[offset2]; p<=p2; p++)
  2624.                     *p = cur_color;
  2625.               }
  2626.               else
  2627.               { /* select segment */
  2628.                 port_out(offset1 >> 16, SEG_SELECT);
  2629.                 /* write color to pixels */
  2630.                 offset1 &= 0xFFFF;
  2631.                 for (p = &graph_mem[offset1], p2 = &graph_mem[0x10000]; p<p2; p++)
  2632.                     *p = cur_color;
  2633.                 /* select segment */
  2634.                 port_out(offset2 >> 16, SEG_SELECT);
  2635.                 /* write color to pixels */
  2636.                 offset2 &= 0xFFFF;
  2637.                 for (p = &graph_mem[0], p2 = &graph_mem[offset2]; p<=p2; p++)
  2638.                     *p = cur_color;
  2639.               }
  2640.           }
  2641.           break;
  2642.     }
  2643. }
  2644.  
  2645.  
  2646. void vga_drawbox (int x1, int y1, int x2, int y2)
  2647. {
  2648.     /* we may assume 0 <= x1 <= x2 and 0 <= y1 <= y2 */
  2649.     int y;
  2650.     for (y = y1; y <= y2; y++)
  2651.         vga_drawhline(x1,x2,y);
  2652. }
  2653.  
  2654.  
  2655. void vga_drawline (int x1, int y1, int x2, int y2)
  2656. {
  2657.     int dx = x2 - x1;
  2658.     int dy = y2 - y1;
  2659.     int ax = ABS(dx) << 1;
  2660.     int ay = ABS(dy) << 1;
  2661.     int sx = (dx >= 0) ? 1 : -1;
  2662.     int sy = (dy >= 0) ? 1 : -1;
  2663.  
  2664.     int x  = x1;
  2665.     int y  = y1;
  2666.  
  2667.     if (ax > ay) {
  2668.         int d = ay - (ax >> 1);
  2669.         while (x != x2) {
  2670.             vga_drawpixel(x, y);
  2671.  
  2672.             if (d > 0 || (d == 0 && sx == 1)) {
  2673.                 y += sy;
  2674.                 d -= ax;
  2675.             }
  2676.             x += sx;
  2677.             d += ay;
  2678.         }
  2679.     } else {
  2680.         int d = ax - (ay >> 1);
  2681.         while (y != y2) {
  2682.             vga_drawpixel(x, y);
  2683.  
  2684.             if (d > 0 || (d == 0 && sy == 1)) {
  2685.                 x += sx;
  2686.                 d -= ay;
  2687.             }
  2688.             y += sy;
  2689.             d += ax;
  2690.         }
  2691.     }
  2692.     vga_drawpixel(x, y);
  2693. }
  2694.  
  2695.  
  2696. int vga_getxdim (void)
  2697. {
  2698.     return cur_info.xdim;
  2699. }
  2700.  
  2701.  
  2702. int vga_getydim (void)
  2703. {
  2704.     return cur_info.ydim;
  2705. }
  2706.  
  2707.  
  2708. int vga_getcolors (void)
  2709. {
  2710.     return cur_info.colors;
  2711. }
  2712.  
  2713.  
  2714. # ============================================================================ #
  2715.  
  2716.  
  2717. int gr_init (sintL width, sintL height, sintL colors)
  2718. {
  2719.     int mode = TEXT;
  2720.  
  2721.     if (vga_hasmode(G320x200x16))
  2722.       { mode = G320x200x16; }
  2723.     if (colors <= 16)
  2724.       { # choose a 16-color mode if possible
  2725.         if (width > 320)
  2726.           { if (vga_hasmode(G640x200x16))
  2727.               { mode = G640x200x16; }
  2728.             if (height > 200 && vga_hasmode(G640x350x16))
  2729.               { mode = G640x350x16; }
  2730.             if (height > 350 && vga_hasmode(G640x480x16))
  2731.               { mode = G640x480x16; }
  2732.           }
  2733.           else
  2734.           { if (height > 200 && vga_hasmode(G320x240x256))
  2735.               { mode = G320x240x256; }
  2736.             if (height > 240 && vga_hasmode(G320x400x256))
  2737.               { mode = G320x400x256; }
  2738.             if (height > 400 && vga_hasmode(G360x480x256))
  2739.               { mode = G360x480x256; }
  2740.             if (width > 360 && vga_hasmode(G640x480x16))
  2741.               { mode = G640x480x16; }
  2742.       }   }
  2743.       else
  2744.       { # choose a 256-color mode
  2745.         if (vga_hasmode(G320x200x256))
  2746.           { mode = G320x200x256; }
  2747.         if (height > 200 && vga_hasmode(G320x240x256))
  2748.           { mode = G320x240x256; }
  2749.         if (height > 240 && vga_hasmode(G320x400x256))
  2750.           { mode = G320x400x256; }
  2751.         if ((width > 320 || height > 400) && vga_hasmode(G360x480x256))
  2752.           { mode = G360x480x256; }
  2753.         if (width > 360 && vga_hasmode(G640x480x256))
  2754.           { mode = G640x480x256; }
  2755.       }
  2756.     if ((width > 640 || height > 480) && vga_hasmode(G800x600x256))
  2757.       { mode = G800x600x256; }
  2758.     if ((width > 800 || height > 600) && vga_hasmode(G1024x768x256))
  2759.       { mode = G1024x768x256; }
  2760.  
  2761.     if (mode == TEXT)
  2762.       return -1;
  2763.  
  2764.     flip_mode = TEXT;
  2765.     if (vga_setmode(mode) < 0)
  2766.       { OS_error(); }
  2767.  
  2768.     return 0;
  2769. }
  2770.  
  2771. void gr_show (void)
  2772. {
  2773.     if (cur_mode == TEXT)
  2774.       { switch_graphics_mode();
  2775.         if (cur_mode == TEXT)
  2776.           { fehler(error,
  2777.                    DEUTSCH ? "Grafik nicht initialisiert." :
  2778.                    ENGLISH ? "graphics not initialized" :
  2779.                    FRANCAIS ? "SystΦme graphique non initialisΘ." :
  2780.                    ""
  2781.                   );
  2782.       }   }
  2783. }
  2784.  
  2785. static struct named_color mono_colors []
  2786.   = { {  0, "BLACK" },
  2787.       { 15, "WHITE" },
  2788.       { 0,  NULL    }
  2789.     };
  2790. static struct named_color EGA_colors []
  2791.   = { {  0, "BLACK"         },
  2792.       {  1, "BLUE"          },
  2793.       {  2, "GREEN"         },
  2794.       {  3, "CYAN"          },
  2795.       {  4, "RED"           },
  2796.       {  5, "MAGENTA"       },
  2797.       {  6, "BROWN"         },
  2798.       {  7, "LIGHT-GRAY"    },
  2799.       {  8, "DARK-GRAY"     },
  2800.       {  9, "LIGHT-BLUE"    },
  2801.       { 10, "LIGHT-GREEN"   },
  2802.       { 11, "LIGHT-CYAN"    },
  2803.       { 12, "LIGHT-RED"     },
  2804.       { 13, "LIGHT-MAGENTA" },
  2805.       { 14, "YELLOW"        },
  2806.       { 15, "WHITE"         },
  2807.       { 0,  NULL            }
  2808.     };
  2809. static struct named_color VGA_colors []
  2810.   = { {  0, "BLACK"         },
  2811.       {  1, "DARK-BLUE"     },
  2812.       {  2, "DARK-GREEN"    },
  2813.       {  3, "DARK-CYAN"     },
  2814.       {  4, "DARK-RED"      },
  2815.       {  5, "DARK-MAGENTA"  },
  2816.       {  9, "BLUE"          },
  2817.       { 10, "GREEN"         },
  2818.       { 11, "CYAN"          },
  2819.       { 12, "RED"           },
  2820.       { 13, "MAGENTA"       },
  2821.       { 14, "YELLOW"        },
  2822.       { 15, "WHITE"         },
  2823.       { 43, "BROWN"         }, # or 66
  2824.       { 26, "DARK-GRAY"     },
  2825.       { 29, "LIGHT-GRAY"    },
  2826.       { 0,  NULL            }
  2827.     };
  2828.  
  2829. struct named_color * gr_colors (void)
  2830. {
  2831.     switch (cur_info.colors)
  2832.       { case 2: return &!mono_colors;
  2833.         case 16: return &!EGA_colors;
  2834.         case 256: return &!VGA_colors;
  2835.         default: NOTREACHED
  2836.       }
  2837. }
  2838.  
  2839. #define gr_xdim  cur_info.xdim
  2840. #define gr_ydim  cur_info.ydim
  2841.  
  2842. int gr_get (sintL x, sintL y)
  2843. {
  2844.     struct dot_args args;
  2845.     gr_show();
  2846.     args.x = x; args.y = y;
  2847.     if (dot_clipping(&cur_clip,&args))
  2848.       return vga_getpixel(args.x,args.y);
  2849.       else
  2850.       return 0;
  2851. }
  2852.  
  2853. void gr_dot (sintL color, sintL x, sintL y)
  2854. {
  2855.     struct dot_args args;
  2856.     gr_show();
  2857.     args.x = x; args.y = y;
  2858.     if (color >= 0 && color < cur_info.colors)
  2859.       if (dot_clipping(&cur_clip,&args))
  2860.         { if (!(color == cur_color)) vga_setcolor(color);
  2861.           vga_drawpixel(args.x,args.y);
  2862.         }
  2863. }
  2864.  
  2865. void gr_box (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  2866. {
  2867.     struct box_args args;
  2868.     gr_show();
  2869.     args.xa = x1; args.ya = y1; args.xb = x2; args.yb = y2;
  2870.     if (color >= 0 && color < cur_info.colors)
  2871.       if (box_clipping(&cur_clip,&args))
  2872.         { if (!(color == cur_color)) vga_setcolor(color);
  2873.           vga_drawbox(args.xa,args.ya,args.xb,args.yb);
  2874.         }
  2875. }
  2876.  
  2877. void gr_clear (sintL color)
  2878. {
  2879.     gr_show();
  2880.     if (color >= 0 && color < cur_info.colors)
  2881.       { if (color==0)
  2882.           { vga_clear(); }
  2883.           else
  2884.           { if (!(color == cur_color)) vga_setcolor(color);
  2885.             vga_drawbox(cur_clip.x1,cur_clip.y1,cur_clip.x2,cur_clip.y2);
  2886.       }   }
  2887. }
  2888.  
  2889. void gr_line (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  2890. {
  2891.     struct line_args args;
  2892.     gr_show();
  2893.     args.xa = x1; args.ya = y1; args.xb = x2; args.yb = y2;
  2894.     if (color >= 0 && color < cur_info.colors)
  2895.       if (line_clipping(&cur_clip,&args))
  2896.         { if (!(color == cur_color)) vga_setcolor(color);
  2897.           vga_drawline(args.xa,args.ya,args.xb,args.yb);
  2898.         }
  2899. }
  2900.  
  2901. #endif # EMUNIX_PORTABEL
  2902.  
  2903. # Painting a text string.
  2904.  
  2905. typedef uint8 fontchar_8_16 [16];
  2906. static fontchar_8_16 font [256] = {
  2907. #ifdef ISOLATIN_CHS
  2908. /* This was produced using the command
  2909.  * hexdump -e '"/" "* %03.3_ax *" "/  {" 15/1 "0x%02X," 1/1 "0x%02X" "},\n"' /usr/lib/kbd/consolefonts/latin | sed -e 's/0 / /g'
  2910.  */
  2911. /* 00 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2912. /* 01 */  {0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00},
  2913. /* 02 */  {0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xE7,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00},
  2914. /* 03 */  {0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00},
  2915. /* 04 */  {0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00},
  2916. /* 05 */  {0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  2917. /* 06 */  {0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  2918. /* 07 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  2919. /* 08 */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  2920. /* 09 */  {0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00},
  2921. /* 0a */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF},
  2922. /* 0b */  {0x00,0x00,0x1E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00},
  2923. /* 0c */  {0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00},
  2924. /* 0d */  {0x00,0x00,0x3F,0x33,0x3F,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00},
  2925. /* 0e */  {0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00},
  2926. /* 0f */  {0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00},
  2927. /* 10 */  {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00},
  2928. /* 11 */  {0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00},
  2929. /* 12 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00},
  2930. /* 13 */  {0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00},
  2931. /* 14 */  {0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00},
  2932. /* 15 */  {0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00},
  2933. /* 16 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00},
  2934. /* 17 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00},
  2935. /* 18 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  2936. /* 19 */  {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00},
  2937. /* 1a */  {0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  2938. /* 1b */  {0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00},
  2939. /* 1c */  {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  2940. /* 1d */  {0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00},
  2941. /* 1e */  {0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00},
  2942. /* 1f */  {0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00},
  2943. /* 20 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2944. /* 21 */  {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  2945. /* 22 */  {0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2946. /* 23 */  {0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00},
  2947. /* 24 */  {0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00},
  2948. /* 25 */  {0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00},
  2949. /* 26 */  {0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  2950. /* 27 */  {0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2951. /* 28 */  {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00},
  2952. /* 29 */  {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00},
  2953. /* 2a */  {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00},
  2954. /* 2b */  {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  2955. /* 2c */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00},
  2956. /* 2d */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2957. /* 2e */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  2958. /* 2f */  {0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00},
  2959. /* 30 */  {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2960. /* 31 */  {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00},
  2961. /* 32 */  {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00},
  2962. /* 33 */  {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2963. /* 34 */  {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00},
  2964. /* 35 */  {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2965. /* 36 */  {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2966. /* 37 */  {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00},
  2967. /* 38 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2968. /* 39 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00},
  2969. /* 3a */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
  2970. /* 3b */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00},
  2971. /* 3c */  {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00},
  2972. /* 3d */  {0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  2973. /* 3e */  {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00},
  2974. /* 3f */  {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  2975. /* 40 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00},
  2976. /* 41 */  {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  2977. /* 42 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00},
  2978. /* 43 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00},
  2979. /* 44 */  {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00},
  2980. /* 45 */  {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
  2981. /* 46 */  {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  2982. /* 47 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00},
  2983. /* 48 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  2984. /* 49 */  {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  2985. /* 4a */  {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00},
  2986. /* 4b */  {0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  2987. /* 4c */  {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
  2988. /* 4d */  {0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  2989. /* 4e */  {0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  2990. /* 4f */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2991. /* 50 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  2992. /* 51 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00},
  2993. /* 52 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  2994. /* 53 */  {0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2995. /* 54 */  {0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  2996. /* 55 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  2997. /* 56 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00},
  2998. /* 57 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00},
  2999. /* 58 */  {0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3000. /* 59 */  {0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3001. /* 5a */  {0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3002. /* 5b */  {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00},
  3003. /* 5c */  {0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00},
  3004. /* 5d */  {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00},
  3005. /* 5e */  {0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3006. /* 5f */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00},
  3007. /* 60 */  {0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3008. /* 61 */  {0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3009. /* 62 */  {0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00},
  3010. /* 63 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3011. /* 64 */  {0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3012. /* 65 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3013. /* 66 */  {0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3014. /* 67 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00},
  3015. /* 68 */  {0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  3016. /* 69 */  {0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3017. /* 6a */  {0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00},
  3018. /* 6b */  {0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00},
  3019. /* 6c */  {0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3020. /* 6d */  {0x00,0x00,0x00,0x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0x00,0x00,0x00,0x00},
  3021. /* 6e */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00},
  3022. /* 6f */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3023. /* 70 */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00},
  3024. /* 71 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00},
  3025. /* 72 */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3026. /* 73 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3027. /* 74 */  {0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00},
  3028. /* 75 */  {0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3029. /* 76 */  {0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00},
  3030. /* 77 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00},
  3031. /* 78 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00},
  3032. /* 79 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00},
  3033. /* 7a */  {0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3034. /* 7b */  {0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00},
  3035. /* 7c */  {0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3036. /* 7d */  {0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00},
  3037. /* 7e */  {0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3038. /* 7f */  {0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00},
  3039. /* 80 */  {0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3040. /* 81 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3041. /* 82 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3042. /* 83 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3043. /* 84 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3044. /* 85 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3045. /* 86 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3046. /* 87 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3047. /* 88 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3048. /* 89 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3049. /* 8a */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3050. /* 8b */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3051. /* 8c */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3052. /* 8d */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3053. /* 8e */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3054. /* 8f */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3055. /* 90 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00},
  3056. /* 91 */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3057. /* 92 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3058. /* 93 */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6F,0x60,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3059. /* 94 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3060. /* 95 */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3061. /* 96 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x60,0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3062. /* 97 */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6F,0x60,0x6F,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3063. /* 98 */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3064. /* 99 */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEC,0x0C,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3065. /* 9a */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3066. /* 9b */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3067. /* 9c */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x0C,0xEC,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3068. /* 9d */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEC,0x0C,0xEC,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3069. /* 9e */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xEF,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3070. /* 9f */  {0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0xEF,0x00,0xEF,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C},
  3071. /* a0 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xFE,0x00,0x00,0x00,0x00},
  3072. /* a1 */  {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00},
  3073. /* a2 */  {0x00,0x00,0x00,0x00,0x10,0x7C,0xD6,0xD0,0xD0,0xD0,0xD6,0x7C,0x10,0x00,0x00,0x00},
  3074. /* a3 */  {0x00,0x00,0x38,0x6C,0x60,0x60,0xF0,0x60,0x60,0x66,0xF6,0x6C,0x00,0x00,0x00,0x00},
  3075. /* a4 */  {0x00,0x00,0x00,0x00,0xC6,0x7C,0x6C,0x6C,0x7C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00},
  3076. /* a5 */  {0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3077. /* a6 */  {0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3078. /* a7 */  {0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00},
  3079. /* a8 */  {0x00,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3080. /* a9 */  {0x00,0x00,0x7E,0xC3,0x99,0xA5,0xA1,0xA5,0x99,0xC3,0x7E,0x00,0x00,0x00,0x00,0x00},
  3081. /* aa */  {0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3082. /* ab */  {0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00},
  3083. /* ac */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00},
  3084. /* ad */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3085. /* ae */  {0x00,0x00,0x7E,0xC3,0xB9,0xA5,0xB9,0xA5,0xA5,0xC3,0x7E,0x00,0x00,0x00,0x00,0x00},
  3086. /* af */  {0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3087. /* b0 */  {0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3088. /* b1 */  {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x7E,0x00,0x00,0x00,0x00},
  3089. /* b2 */  {0x38,0x6C,0x18,0x30,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3090. /* b3 */  {0x38,0x6C,0x18,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3091. /* b4 */  {0x00,0x18,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3092. /* b5 */  {0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xF6,0xC0,0xC0,0xC0,0x00},
  3093. /* b6 */  {0x00,0x00,0x7F,0xF6,0xF6,0x76,0x36,0x36,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x00},
  3094. /* b7 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3095. /* b8 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x6C,0x38,0x00},
  3096. /* b9 */  {0x30,0x70,0x30,0x30,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3097. /* ba */  {0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3098. /* bb */  {0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00},
  3099. /* bc */  {0x00,0x60,0xE0,0x66,0x6C,0x18,0x36,0x6E,0xDE,0x36,0x7E,0x06,0x06,0x00,0x00,0x00},
  3100. /* bd */  {0x00,0x60,0xE0,0x66,0x6C,0x18,0x30,0x60,0xDC,0x36,0x0C,0x18,0x3E,0x00,0x00,0x00},
  3101. /* be */  {0x00,0xE0,0x30,0x66,0x3C,0xF8,0x36,0x6E,0xDE,0x36,0x7E,0x06,0x06,0x00,0x00,0x00},
  3102. /* bf */  {0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x30,0x60,0xC6,0xC6,0x7C,0x00,0x00},
  3103. /* c0 */  {0x60,0x30,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3104. /* c1 */  {0x0C,0x18,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3105. /* c2 */  {0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3106. /* c3 */  {0x76,0xDC,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3107. /* c4 */  {0x00,0x6C,0x6C,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3108. /* c5 */  {0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3109. /* c6 */  {0x00,0x00,0x3E,0x78,0xD8,0xD8,0xFC,0xD8,0xD8,0xD8,0xD8,0xDE,0x00,0x00,0x00,0x00},
  3110. /* c7 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x66,0x3C,0x00},
  3111. /* c8 */  {0x60,0x30,0x18,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00},
  3112. /* c9 */  {0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00},
  3113. /* ca */  {0x10,0x38,0x6C,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00},
  3114. /* cb */  {0x00,0x6C,0x6C,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00},
  3115. /* cc */  {0x60,0x30,0x18,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3116. /* cd */  {0x06,0x0C,0x18,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3117. /* ce */  {0x18,0x3C,0x66,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3118. /* cf */  {0x00,0x66,0x66,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3119. /* d0 */  {0x00,0x00,0xF8,0x6C,0x66,0x66,0xF6,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00},
  3120. /* d1 */  {0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3121. /* d2 */  {0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3122. /* d3 */  {0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3123. /* d4 */  {0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3124. /* d5 */  {0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3125. /* d6 */  {0x00,0x6C,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3126. /* d7 */  {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00},
  3127. /* d8 */  {0x00,0x00,0x7E,0xC6,0xCE,0xCE,0xDE,0xF6,0xE6,0xE6,0xC6,0xFC,0x00,0x00,0x00,0x00},
  3128. /* d9 */  {0x60,0x30,0x18,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3129. /* da */  {0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3130. /* db */  {0x10,0x38,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3131. /* dc */  {0x00,0x6C,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3132. /* dd */  {0x06,0x0C,0x18,0x00,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3133. /* de */  {0x00,0x00,0xF0,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00},
  3134. /* df */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xCC,0xC6,0xC6,0xC6,0xD6,0xDC,0x80,0x00,0x00,0x00},
  3135. /* e0 */  {0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3136. /* e1 */  {0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3137. /* e2 */  {0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3138. /* e3 */  {0x00,0x00,0x76,0xDC,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3139. /* e4 */  {0x00,0x00,0x6C,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3140. /* e5 */  {0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3141. /* e6 */  {0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0x1B,0x7F,0xD8,0xDB,0x7E,0x00,0x00,0x00,0x00},
  3142. /* e7 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x6C,0x38,0x00},
  3143. /* e8 */  {0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3144. /* e9 */  {0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3145. /* ea */  {0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3146. /* eb */  {0x00,0x00,0x6C,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3147. /* ec */  {0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3148. /* ed */  {0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3149. /* ee */  {0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3150. /* ef */  {0x00,0x00,0x6C,0x6C,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3151. /* f0 */  {0x00,0x78,0x30,0x78,0x0C,0x7E,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3152. /* f1 */  {0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00},
  3153. /* f2 */  {0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3154. /* f3 */  {0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3155. /* f4 */  {0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3156. /* f5 */  {0x00,0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3157. /* f6 */  {0x00,0x00,0x6C,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3158. /* f7 */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
  3159. /* f8 */  {0x00,0x00,0x00,0x00,0x00,0x7E,0xCE,0xDE,0xFE,0xF6,0xE6,0xFC,0x00,0x00,0x00,0x00},
  3160. /* f9 */  {0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3161. /* fa */  {0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3162. /* fb */  {0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3163. /* fc */  {0x00,0x00,0xCC,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3164. /* fd */  {0x00,0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00},
  3165. /* fe */  {0x00,0x00,0xF0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,0x00},
  3166. /* ff */  {0x00,0x00,0x6C,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00},
  3167. #endif
  3168. #ifdef IBMPC_CHS
  3169. /* This was produced using the command
  3170.  * hexdump -e '"/" "* %03.3_ax *" "/  {" 15/1 "0x%02X," 1/1 "0x%02X" "},\n"' /usr/lib/kbd/consolefonts/default | sed -e 's/0 / /g'
  3171.  */
  3172. /* 00 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3173. /* 01 */  {0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00},
  3174. /* 02 */  {0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xE7,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00},
  3175. /* 03 */  {0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00},
  3176. /* 04 */  {0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00},
  3177. /* 05 */  {0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3178. /* 06 */  {0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3179. /* 07 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  3180. /* 08 */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  3181. /* 09 */  {0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00},
  3182. /* 0a */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF},
  3183. /* 0b */  {0x00,0x00,0x1E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00},
  3184. /* 0c */  {0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00},
  3185. /* 0d */  {0x00,0x00,0x3F,0x33,0x3F,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00},
  3186. /* 0e */  {0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00},
  3187. /* 0f */  {0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00},
  3188. /* 10 */  {0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00},
  3189. /* 11 */  {0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00},
  3190. /* 12 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00},
  3191. /* 13 */  {0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00},
  3192. /* 14 */  {0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00},
  3193. /* 15 */  {0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00},
  3194. /* 16 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00},
  3195. /* 17 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00},
  3196. /* 18 */  {0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3197. /* 19 */  {0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00},
  3198. /* 1a */  {0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  3199. /* 1b */  {0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00},
  3200. /* 1c */  {0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},
  3201. /* 1d */  {0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00},
  3202. /* 1e */  {0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00},
  3203. /* 1f */  {0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00},
  3204. /* 20 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3205. /* 21 */  {0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  3206. /* 22 */  {0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3207. /* 23 */  {0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00},
  3208. /* 24 */  {0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00},
  3209. /* 25 */  {0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00},
  3210. /* 26 */  {0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3211. /* 27 */  {0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3212. /* 28 */  {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00},
  3213. /* 29 */  {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00},
  3214. /* 2a */  {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00},
  3215. /* 2b */  {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00},
  3216. /* 2c */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00},
  3217. /* 2d */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3218. /* 2e */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  3219. /* 2f */  {0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00},
  3220. /* 30 */  {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3221. /* 31 */  {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00},
  3222. /* 32 */  {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3223. /* 33 */  {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3224. /* 34 */  {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00},
  3225. /* 35 */  {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3226. /* 36 */  {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3227. /* 37 */  {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00},
  3228. /* 38 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3229. /* 39 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00},
  3230. /* 3a */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
  3231. /* 3b */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00},
  3232. /* 3c */  {0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00},
  3233. /* 3d */  {0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3234. /* 3e */  {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00},
  3235. /* 3f */  {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00},
  3236. /* 40 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00},
  3237. /* 41 */  {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3238. /* 42 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00},
  3239. /* 43 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00},
  3240. /* 44 */  {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00},
  3241. /* 45 */  {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
  3242. /* 46 */  {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3243. /* 47 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00},
  3244. /* 48 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3245. /* 49 */  {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3246. /* 4a */  {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00},
  3247. /* 4b */  {0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  3248. /* 4c */  {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00},
  3249. /* 4d */  {0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3250. /* 4e */  {0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3251. /* 4f */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3252. /* 50 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3253. /* 51 */  {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00},
  3254. /* 52 */  {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  3255. /* 53 */  {0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3256. /* 54 */  {0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3257. /* 55 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3258. /* 56 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00},
  3259. /* 57 */  {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00},
  3260. /* 58 */  {0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3261. /* 59 */  {0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3262. /* 5a */  {0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3263. /* 5b */  {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00},
  3264. /* 5c */  {0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00},
  3265. /* 5d */  {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00},
  3266. /* 5e */  {0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3267. /* 5f */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00},
  3268. /* 60 */  {0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3269. /* 61 */  {0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3270. /* 62 */  {0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00},
  3271. /* 63 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3272. /* 64 */  {0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3273. /* 65 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3274. /* 66 */  {0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3275. /* 67 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00},
  3276. /* 68 */  {0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00},
  3277. /* 69 */  {0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3278. /* 6a */  {0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00},
  3279. /* 6b */  {0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00},
  3280. /* 6c */  {0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3281. /* 6d */  {0x00,0x00,0x00,0x00,0x00,0xEC,0xFE,0xD6,0xD6,0xD6,0xD6,0xC6,0x00,0x00,0x00,0x00},
  3282. /* 6e */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00},
  3283. /* 6f */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3284. /* 70 */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00},
  3285. /* 71 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00},
  3286. /* 72 */  {0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00},
  3287. /* 73 */  {0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3288. /* 74 */  {0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00},
  3289. /* 75 */  {0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3290. /* 76 */  {0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00},
  3291. /* 77 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00},
  3292. /* 78 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00},
  3293. /* 79 */  {0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00},
  3294. /* 7a */  {0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3295. /* 7b */  {0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00},
  3296. /* 7c */  {0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3297. /* 7d */  {0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00},
  3298. /* 7e */  {0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3299. /* 7f */  {0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00},
  3300. /* 80 */  {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00},
  3301. /* 81 */  {0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3302. /* 82 */  {0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3303. /* 83 */  {0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3304. /* 84 */  {0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3305. /* 85 */  {0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3306. /* 86 */  {0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3307. /* 87 */  {0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00},
  3308. /* 88 */  {0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3309. /* 89 */  {0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3310. /* 8a */  {0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3311. /* 8b */  {0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3312. /* 8c */  {0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3313. /* 8d */  {0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3314. /* 8e */  {0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3315. /* 8f */  {0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3316. /* 90 */  {0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00},
  3317. /* 91 */  {0x00,0x00,0x00,0x00,0x6C,0xFE,0xB2,0x32,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00},
  3318. /* 92 */  {0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00},
  3319. /* 93 */  {0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3320. /* 94 */  {0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3321. /* 95 */  {0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3322. /* 96 */  {0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3323. /* 97 */  {0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3324. /* 98 */  {0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00},
  3325. /* 99 */  {0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3326. /* 9a */  {0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3327. /* 9b */  {0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00},
  3328. /* 9c */  {0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00},
  3329. /* 9d */  {0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3330. /* 9e */  {0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00},
  3331. /* 9f */  {0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00},
  3332. /* a0 */  {0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3333. /* a1 */  {0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00},
  3334. /* a2 */  {0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3335. /* a3 */  {0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00},
  3336. /* a4 */  {0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00},
  3337. /* a5 */  {0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3338. /* a6 */  {0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3339. /* a7 */  {0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3340. /* a8 */  {0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00},
  3341. /* a9 */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00},
  3342. /* aa */  {0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00},
  3343. /* ab */  {0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00},
  3344. /* ac */  {0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00},
  3345. /* ad */  {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00},
  3346. /* ae */  {0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00},
  3347. /* af */  {0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00},
  3348. /* b0 */  {0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44},
  3349. /* b1 */  {0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA},
  3350. /* b2 */  {0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77},
  3351. /* b3 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3352. /* b4 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3353. /* b5 */  {0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3354. /* b6 */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3355. /* b7 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3356. /* b8 */  {0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3357. /* b9 */  {0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3358. /* ba */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3359. /* bb */  {0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3360. /* bc */  {0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3361. /* bd */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3362. /* be */  {0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3363. /* bf */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3364. /* c0 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3365. /* c1 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3366. /* c2 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3367. /* c3 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3368. /* c4 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3369. /* c5 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3370. /* c6 */  {0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3371. /* c7 */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3372. /* c8 */  {0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3373. /* c9 */  {0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3374. /* ca */  {0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3375. /* cb */  {0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3376. /* cc */  {0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3377. /* cd */  {0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3378. /* ce */  {0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3379. /* cf */  {0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3380. /* d0 */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3381. /* d1 */  {0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3382. /* d2 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3383. /* d3 */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3384. /* d4 */  {0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3385. /* d5 */  {0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3386. /* d6 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3387. /* d7 */  {0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36},
  3388. /* d8 */  {0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3389. /* d9 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3390. /* da */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3391. /* db */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  3392. /* dc */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  3393. /* dd */  {0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0},
  3394. /* de */  {0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F},
  3395. /* df */  {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3396. /* e0 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00},
  3397. /* e1 */  {0x00,0x00,0x78,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00},
  3398. /* e2 */  {0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00},
  3399. /* e3 */  {0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00},
  3400. /* e4 */  {0x00,0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00},
  3401. /* e5 */  {0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00},
  3402. /* e6 */  {0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,0x00,0x00},
  3403. /* e7 */  {0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00},
  3404. /* e8 */  {0x00,0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00},
  3405. /* e9 */  {0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00},
  3406. /* ea */  {0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00},
  3407. /* eb */  {0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00},
  3408. /* ec */  {0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00},
  3409. /* ed */  {0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00},
  3410. /* ee */  {0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00},
  3411. /* ef */  {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00},
  3412. /* f0 */  {0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00},
  3413. /* f1 */  {0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00},
  3414. /* f2 */  {0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00},
  3415. /* f3 */  {0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00},
  3416. /* f4 */  {0x00,0x00,0x0E,0x1B,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18},
  3417. /* f5 */  {0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00},
  3418. /* f6 */  {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00},
  3419. /* f7 */  {0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00},
  3420. /* f8 */  {0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3421. /* f9 */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3422. /* fa */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3423. /* fb */  {0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00},
  3424. /* fc */  {0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3425. /* fd */  {0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3426. /* fe */  {0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00},
  3427. /* ff */  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  3428. #endif
  3429. };
  3430.  
  3431. void gr_text (sintL color, sintL* x, sintL* y, sintL dir, uintB* charptr, uintL count)
  3432. {
  3433.     var sintL dx, dy, x1, y1;
  3434.     switch (dir)
  3435.       { case 0: dx = 1; dy = 0; break;
  3436.         case 90: dx = 0; dy = -1; break;
  3437.         case 180: dx = -1; dy = 0; break;
  3438.         case 270: dx = 0; dy = 1; break;
  3439.         default: return;
  3440.       }
  3441.     x1 = *x; y1 = *y;
  3442.     dotimesL(count,count,
  3443.       { var uintB c = *charptr++;
  3444.         var fontchar_8_16* f = &font[c];
  3445.         var uintL i;
  3446.         var uintL j;
  3447.         var sintL x2;
  3448.         var sintL y2;
  3449.         for (i = 0; i < 8; i++, x1 += dx, y1 += dy)
  3450.           for (j = 0, x2 = x1, y2 = y1; j < 16; j++, x2 -= dy, y2 += dx)
  3451.             if ((*f)[j] & bit(7-i))
  3452.               gr_dot(color,x2,y2);
  3453.         
  3454.       });
  3455.     *x = x1; *y = y1;
  3456. }
  3457.  
  3458. #endif # GRAPHICS_SWITCH
  3459.  
  3460. #ifdef GRAPHICS_X
  3461.  
  3462. #include <X11/X.h>
  3463. #include <X11/Xlib.h>
  3464. #include <X11/Xutil.h>
  3465.  
  3466. static Display* display = NULL;  # X server connection
  3467. static int screen;               # the default screen number
  3468. #define COLOR_WHITE  WhitePixel(display,screen)
  3469. #define COLOR_BLACK  BlackPixel(display,screen)
  3470. static Window window;            # window ID
  3471. static int x_xdim;               # width of window
  3472. static int x_ydim;               # height of window
  3473. static GC draw_gc;               # graphics context for drawing
  3474. static sintL draw_color;         # current drawing color
  3475.  
  3476. int x_fatal_error_handler (Display* display)
  3477. {
  3478.     fehler(error,
  3479.            "X I/O error"
  3480.           );
  3481. }
  3482.  
  3483. int x_init (sintL width, sintL height, sintL colors)
  3484. {
  3485.     # Open X display:
  3486.     if (display==NULL)
  3487.       { display = XOpenDisplay(NULL);
  3488.         if (display==NULL)
  3489.           { return -1; }
  3490.       }
  3491.     # Get its default screen number:
  3492.     screen = DefaultScreen(display);
  3493.     # Set the error handler:
  3494.     XSetIOErrorHandler(&x_fatal_error_handler);
  3495.  
  3496.     # Open the window:
  3497.     {   XFontStruct* fontstruct;   # font descriptor
  3498.         XSizeHints*  sizehints;    # size hints for window manager
  3499.         XWMHints*    wmhints;      # hints for window manager
  3500.  
  3501.         # Load default font:
  3502.         fontstruct = XLoadQueryFont(display,"fixed");
  3503.         if (fontstruct==NULL)
  3504.           { return -1; }
  3505.  
  3506.         # Select colors:
  3507.         {
  3508.             #define NUMCOLORS  16
  3509.             static char* colorname [NUMCOLORS] =
  3510.               { "WHITE",  "BLACK",    "PINK",    "RED",
  3511.                 "ORANGE", "YELLOW",   "GREEN",   "TURQUOISE",
  3512.                 "BLUE",   "LAVENDER", "MAGENTA", "PURPLE",
  3513.                 "GOLD",   "BROWN",    "CYAN",    "LIGHT GRAY"
  3514.               };
  3515.             Xcolor xcolor [NUMCOLORS];  # the colors
  3516.             Xcolor unused_color;
  3517.             int numcolors = (colors <= 2 ? 2 : NUMCOLORS);
  3518.             int i;
  3519.             for (i = 0; i < numcolors; i++)
  3520.                 XAllocNamedColor (display, DefaultColormap(display,screen),
  3521.                                            colorname[i],
  3522.                                            &xcolor[i],   # color on screen
  3523.                                            &unused_color # exact color: unused
  3524.                                  );
  3525.         }
  3526.  
  3527.         # Size hints for the Window Manager:
  3528.         sizehints = XAllocSizeHints();
  3529.         if (sizehints==NULL)
  3530.           return -1;
  3531.         sizehints->flags = PSize | PPosition;
  3532.         # size: width, height
  3533.         sizehints->width = width; sizehints->height = height;
  3534.         # position: centered
  3535.         sizehints->x = DisplayWidth(display,screen) - sizehints->width;
  3536.         if (sizehints->x < 0) { sizehints->x = 0; }
  3537.         sizehints->x >>= 1;
  3538.         sizehints->y = DisplayHeight(display,screen) - sizehints->height;
  3539.         if (sizehints->y < 0) { sizehints->y = 0; }
  3540.         sizehints->y >>= 1;
  3541.  
  3542.         # Get a window.
  3543.         # Background will be COLOR_WHITE, Foreground will be COLOR_BLACK.
  3544.         window = XCreateSimpleWindow (display, RootWindow(display,screen),
  3545.                                       sizehints->x, sizehints->y,
  3546.                                       sizehints->width, sizehints->height,
  3547.                                       1, # border width
  3548.                                       COLOR_BLACK, # border color
  3549.                                       COLOR_WHITE  # background color
  3550.                                      );
  3551.  
  3552.         # Attach a label to the window.
  3553.         # XSetStandardProperties oder XSetWMProperties ??
  3554.         XSetStandardProperties(display,window,
  3555.                                "CLISP graphics", # window label
  3556.                                "CLISP graphics", # icon label
  3557.                                None,
  3558.                                NULL, 0, # argv and argc
  3559.                                sizehints # size hints
  3560.                               );
  3561.  
  3562.         # window manager hints
  3563.         wmhints = XAllocWMHints();
  3564.         if (wmhints==NULL)
  3565.           { return -1; }
  3566.         wmhints->flags = InputHint | StateHint;
  3567.         wmhints->input = FALSE; wmhints->state = NormalState;
  3568.         XSetWMHints(display,window, wmhints);
  3569.  
  3570.         # Set up colors.
  3571.         {   var XSetWindowAttributes xswa;
  3572.             xswa.colormap = DefaultColormap(display,screen);
  3573.             XChangeWindowAttributes (display,window, CWColormap, &xswa);
  3574.         }
  3575.  
  3576.         # Set up graphics context.
  3577.         {   var XGCValues gcv;
  3578.             gcv.font = fontstruct->fid;
  3579.             gcv.background = COLOR_WHITE;
  3580.             gcv.foreground = draw_color = COLOR_BLACK;
  3581.             gcv.plane_mask = AllPlanes;
  3582.             draw_gc = XCreateGC (display,window,
  3583.                                  GCPlaneMask | GCFont | GCForeground | GCBackground,
  3584.                                  &gcv
  3585.                                 );
  3586.         }
  3587.  
  3588.         # Specify the events we are interested in.
  3589.         XSelectInput (display,window, StructureNotifyMask | ExposureMask);
  3590.  
  3591.         # Finally, make the window visible.
  3592.         XMapWindow (display,window);
  3593.  
  3594.         # Don't laugh, but we have to wait until the window really gets visible.
  3595.         loop # a small event-dispatch loop
  3596.           { var XEvent event;
  3597.             XWindowEvent (display,window, StructureNotifyMask, &event);
  3598.             if (event.type == MapNotify)
  3599.               break;
  3600.           }
  3601.  
  3602.         # Clear the window.
  3603.         XClearWindow(display,window);
  3604.  
  3605.     }
  3606.     return 0;
  3607. }
  3608.  
  3609. # NB: XCloseDisplay(display); ist nicht n÷tig. Das erledigt der Window-Manager
  3610. # von selbst, wenn unser Programm beendet wird.
  3611. # XFreeGC(display,draw_gc);
  3612. # XUnloadFont(display,fontstruct->fid);
  3613. # XCloseDisplay(display);
  3614.  
  3615. void x_show (void)
  3616. { # Do nothing, even if the window is iconified.
  3617. }
  3618.  
  3619. void x_dot (sintL color, sintL x, sintL y)
  3620. {
  3621.     if (!(color==draw_color))
  3622.       { XSetForeground(display,draw_gc,color); draw_color = color; }
  3623.     XDrawPoint(display,window, draw_gc, x,y);
  3624. }
  3625.  
  3626. void x_box (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  3627. {
  3628.     if (!(color==draw_color))
  3629.       { XSetForeground(display,draw_gc,color); draw_color = color; }
  3630.     if (x1 > x2) swap(sintL,x1,x2);
  3631.     if (y1 > y2) swap(sintL,y1,y2);
  3632.     XDrawRectangle(display,window, draw_gc, x1,y1, x2-x1,y2-y1);
  3633. }
  3634.  
  3635. void x_clear (sintL color)
  3636. {
  3637.     if (color == COLOR_WHITE)
  3638.       { XClearWindow(display,window); }
  3639.       else
  3640.       ??
  3641. }
  3642.  
  3643. void x_line (sintL color, sintL x1, sintL y1, sintL x2, sintL y2)
  3644. {
  3645.     if (!(color==draw_color))
  3646.       { XSetForeground(display,draw_gc,color); draw_color = color; }
  3647.     XDrawLine(display,window, draw_gc, x1,y1, x2,y2);
  3648. }
  3649.  
  3650. Fehlen:
  3651. # x_colors()                    liefert einen Array von benannten Farben.
  3652. # x_clear(color);               l÷scht den gesamten Grafik-Bildschirm.
  3653. # x_get(x,y)                    liefert die Farbe des Punktes (x,y)
  3654.  
  3655. x_text() { XDrawString (display,window, ...) }
  3656.  
  3657. #endif # GRAPHICS_X
  3658.  
  3659. #ifdef GRAPHICS_SUN
  3660.  
  3661. #include <suntool/sunview.h>
  3662. #include <suntool/canvas.h>
  3663. #include <suntool/textsw.h>
  3664. #include <suntool/panel.h>
  3665.  
  3666. static Frame screen;
  3667. static Canvas canvas;
  3668. static Pixwin* pw;
  3669. static Pixfont* font;
  3670.  
  3671. void sun_init (sintL width, sintL height, sintL colors)
  3672. {
  3673.     screen = window_create (NULL,
  3674.                             FRAME,
  3675.                             FRAME_LABEL, "CLISP graphics",
  3676.                           # WIN_ERROR_MSG, "must be in SunView/SunTools",
  3677.                             0);
  3678.     canvas = window_create (screen,
  3679.                             CANVAS,
  3680.                             WIN_WIDTH, width,
  3681.                             WIN_HEIGHT, height,
  3682.                             0);
  3683.     window_fit(screen);
  3684.     pw = canvas_pixwin(canvas);
  3685.     font = pw_pfsysopen();
  3686.     pw_vector(...);
  3687.     pw_char(pw,?,?,PIX_SRC|PIX_DST,font,ch);
  3688.     window_main_loop(screen);
  3689. }
  3690.  
  3691. #endif # GRAPHICS_SUN
  3692.  
  3693.  
  3694. # Lisp-Funktionen:
  3695.  
  3696. # (SYS::GRAPH-INIT [width [height [colors]]])
  3697. LISPFUN(gr_init,0,3,norest,nokey,0,NIL)
  3698. { { var reg2 object width = STACK_2;
  3699.     var reg4 object height = STACK_1;
  3700.     var reg5 object colors = STACK_0;
  3701.     var reg1 sintL w = (eq(width,unbound) ? 400 : I_to_L(width));
  3702.     var reg3 sintL h = (eq(height,unbound) ? 3*(w>>2) : I_to_L(height));
  3703.     if (gr_init(w, h, (eq(colors,unbound) ? 16 : I_to_L(colors))) < 0)
  3704.       { pushSTACK(S(gr_init));
  3705.         fehler(error,
  3706.                DEUTSCH ? "~: Kann nicht in Grafik-Modus schalten." :
  3707.                ENGLISH ? "~: cannot switch to graphics mode" :
  3708.                FRANCAIS ? "~ : Impossible d'arriver au mode graphique." :
  3709.                ""
  3710.               );
  3711.       }
  3712.     skipSTACK(3);
  3713.   }
  3714.   # Aliste der Farben als Wert:
  3715.   { var reg1 struct named_color * p = gr_colors();
  3716.     var reg3 uintC count = 0;
  3717.     while (p->name) { p++; count++; }
  3718.     pushSTACK(NIL);
  3719.     dotimesC(count,count,
  3720.       {  p--;
  3721.          pushSTACK(allocate_cons());
  3722.          pushSTACK(allocate_cons());
  3723.        { var reg4 object name = intern_keyword(asciz_to_string(p->name));
  3724.          var reg2 object acons = popSTACK();
  3725.          Car(acons) = name; Cdr(acons) = fixnum(p->color);
  3726.         {var reg3 object lcons = popSTACK();
  3727.          Car(lcons) = acons; Cdr(lcons) = STACK_0;
  3728.          STACK_0 = lcons;
  3729.       }}});
  3730.     value1 = popSTACK(); mv_count=1;
  3731. } }
  3732.  
  3733. # (SYS::GRAPH-SHOW)
  3734. LISPFUNN(gr_show,0)
  3735. { gr_show();
  3736.   value1 = NIL; mv_count=0;
  3737. }
  3738.  
  3739. # (SYS::GRAPH-CLEAR [color])
  3740. LISPFUN(gr_clear,0,1,norest,nokey,0,NIL)
  3741. { var reg1 object color = popSTACK();
  3742.   gr_clear(eq(color,unbound) ? 0 : I_to_L(color));
  3743.   value1 = NIL; mv_count=0;
  3744. }
  3745.  
  3746. # (SYS::GRAPH-DIMS)
  3747. LISPFUNN(gr_dims,0)
  3748. { value1 = fixnum(gr_xdim); value2 = fixnum(gr_ydim); mv_count=2; }
  3749.  
  3750. # (SYS::GRAPH-DOT x y [color])
  3751. LISPFUN(gr_dot,2,1,norest,nokey,0,NIL)
  3752. { var reg1 object color = STACK_0;
  3753.   var reg2 sintL x = I_to_L(STACK_2);
  3754.   var reg3 sintL y = I_to_L(STACK_1);
  3755.   if (eq(color,unbound))
  3756.     { value1 = fixnum(gr_get(x,y)); }
  3757.     else
  3758.     { gr_dot(I_to_L(color),x,y); value1 = color; }
  3759.   mv_count=1;
  3760.   skipSTACK(3);
  3761. }
  3762.  
  3763. # (SYS::GRAPH-BOX x1 y1 x2 y2 color)
  3764. LISPFUNN(gr_box,5)
  3765. { var reg1 object color = STACK_0;
  3766.   var reg2 sintL x1 = I_to_L(STACK_4);
  3767.   var reg3 sintL y1 = I_to_L(STACK_3);
  3768.   var reg4 sintL x2 = I_to_L(STACK_2);
  3769.   var reg5 sintL y2 = I_to_L(STACK_1);
  3770.   gr_box(I_to_L(color),x1,y1,x2,y2);
  3771.   value1 = NIL; mv_count=0;
  3772.   skipSTACK(5);
  3773. }
  3774.  
  3775. # (SYS::GRAPH-LINE x1 y1 x2 y2 color)
  3776. LISPFUNN(gr_line,5)
  3777. { var reg1 object color = STACK_0;
  3778.   var reg2 sintL x1 = I_to_L(STACK_4);
  3779.   var reg3 sintL y1 = I_to_L(STACK_3);
  3780.   var reg4 sintL x2 = I_to_L(STACK_2);
  3781.   var reg5 sintL y2 = I_to_L(STACK_1);
  3782.   gr_line(I_to_L(color),x1,y1,x2,y2);
  3783.   value1 = NIL; mv_count=0;
  3784.   skipSTACK(5);
  3785. }
  3786.  
  3787. # (SYS::GRAPH-TEXT x y dir string color)
  3788. LISPFUNN(gr_text,5)
  3789. { var reg3 object color = STACK_0;
  3790.   var sintL x = I_to_L(STACK_4);
  3791.   var sintL y = I_to_L(STACK_3);
  3792.   var reg2 sintL dir = I_to_L(STACK_2);
  3793.   var uintL len;
  3794.   var reg1 uintB* charptr = unpack_string(STACK_1,&len);
  3795.   gr_text(I_to_L(color),&x,&y,dir,charptr,len);
  3796.   pushSTACK(L_to_I(y)); value1 = L_to_I(x); value2 = popSTACK(); mv_count=2;
  3797.   skipSTACK(5);
  3798. }
  3799.  
  3800. #endif # GRAPHICS
  3801.  
  3802.