home *** CD-ROM | disk | FTP | other *** search
/ HomeWare 14 / HOMEWARE14.bin / prog / tee_src.arj / REDIRECT.C next >
C/C++ Source or Header  |  1993-06-07  |  10KB  |  379 lines

  1. //      This source was last touched on 02/16/91
  2. //      and except for some comments it has not changed.
  3. //      so parden the bad programming or flaws you might find,
  4. //      I have learned _much_ even since since then.
  5. //
  6. //      Peter Birch
  7. //      06/07/93
  8. //      Microsoft C
  9. //      Please do not remove my name from this source
  10. //      or charge others for this program, Thank you!
  11.  
  12. /*
  13. ** send all output of a called progam to a user defined window
  14. **
  15. **
  16. ** Peter Birch
  17. **
  18. */
  19.  
  20. #include <dos.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <graph.h>
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <process.h>
  27.  
  28. #define VGA             4
  29. #define EGA             3
  30. #define CGA             2
  31. #define MDA             1
  32.  
  33. typedef struct
  34. {
  35.     unsigned es, ds, di, si, bp, sp,
  36.              bx, dx, cx, ax, ip, cs,
  37.              flgs;
  38. } interrupt_regs;
  39.  
  40. typedef unsigned long ulong;
  41. typedef unsigned int uint;
  42. typedef unsigned char uchar;
  43.  
  44.  
  45. /* internal function prototypes */
  46. int main (int argc, char **argv);
  47. void interrupt cdecl _far int21_handler (interrupt_regs r);
  48. ulong get_video_address (void);
  49. void text (char *ptr);
  50. void usage (void);
  51. void scroll (uchar lines);
  52.  
  53. /* holds character to print */
  54. /* all chars in my functions are printed one at a time */
  55. char    buff[ 2] = "\0\0";
  56.  
  57. char    far *ptr,
  58.         far *screen_ptr = NULL;
  59.  
  60. uchar   top     = 0,
  61.         left    = 0,
  62.         bottom  = 24,
  63.         right   = 79,
  64.         row     = 0,
  65.         col     = 0,
  66.         color   = 7;
  67.  
  68. int     wrap = 0;
  69.  
  70. void    (interrupt cdecl _far *int21_vector)(); /* original int 21 vector owner */
  71.  
  72.  
  73.  
  74. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  75. //  Function....: main
  76. //  Author......: Peter Birch
  77. //  Date Created: Thu  08-15-1991
  78. //  Description.: send all output of a called progam to a user defined window
  79. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  80.  
  81. int main (int argc, char **argv)
  82. {
  83.     int i;
  84.  
  85.     /* has screen_ptr been initialized? */
  86.     if (screen_ptr == NULL)
  87.     {
  88.         screen_ptr = (char far *)get_video_address();
  89.     }
  90.  
  91.     if (argc > 5)
  92.     {
  93.         /* look for switches, they must be first on the command line. */
  94.         i = 1;
  95.         while (argv[ i][ 0] == '-' || argv[ i][ 0] == '/')
  96.         {
  97.             switch (argv[ i][ 1])
  98.             {
  99.                 case 'c':               /* color */
  100.                 case 'C':
  101.                     color = (uchar)atoi(&(argv[ i][ 2]));
  102.                     break;
  103.  
  104.                 case 'w':               /* wrap long lines */
  105.                 case 'W':
  106.                     wrap = 1;
  107.                     break;
  108.  
  109.                 default:
  110.                     usage();
  111.                     break;
  112.             }
  113.             ++i;
  114.         }
  115.  
  116.         /* create window for output */
  117.         top     = (uchar) atoi (argv[ i++]); /* top */
  118.         left    = (uchar) atoi (argv[ i++]); /* left */
  119.         bottom  = (uchar) atoi (argv[ i++]); /* bottom */
  120.         right   = (uchar) atoi (argv[ i++]); /* right */
  121.  
  122.         col = left;
  123.         row = top;
  124.  
  125.         /* clear window */
  126.         scroll (0);
  127.  
  128.         /* save old interrupt 21 vector */
  129.         int21_vector = _dos_getvect (0x21);
  130.  
  131.         /* set int21 to call my interrupt function */
  132.         _dos_setvect (0x21, int21_handler);
  133.  
  134.         /* execute program passed on command line */
  135.         spawnvp (P_WAIT, argv[ i], &(argv[ i]));
  136.  
  137.         /* restore int21 handler to original function */
  138.         _dos_setvect (0x21, int21_vector);
  139.     }
  140.     else
  141.     {
  142.         usage();
  143.     }
  144.  
  145.     return (0);
  146. }
  147.  
  148.  
  149. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  150. //  Function....: int21_handler
  151. //  Author......: Peter Birch
  152. //  Date Created: Thu  08-15-1991
  153. //  Description.: my int 21 handler
  154. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  155.  
  156. void interrupt cdecl _far int21_handler (interrupt_regs r)
  157. {
  158.     switch (r.ax >> 8)        /* ah */
  159.     {
  160.         case 0x02: /* function 2 (display character in dl register) */
  161.             buff[ 0] = (uchar)(r.dx & 0xff); /* dl */
  162.             text (buff);
  163.             break;
  164.  
  165.         case 0x06: /* function 6 (direct console i/o) */
  166.             /* output requested? */
  167.             if ((uchar)(r.dx & 0xff) != 0xff)  /* dl */
  168.             {
  169.                 buff[ 0] = (uchar)(r.dx & 0xff);  /* dl */
  170.                 text (buff);
  171.             }
  172.             else
  173.             {
  174.                 _chain_intr (int21_vector);
  175.             }
  176.             break;
  177.  
  178.         case 0x09:      /* function 9 (print dollar-sign delimited string) */
  179.         {
  180.             FP_SEG (ptr) = r.ds;
  181.             FP_OFF (ptr) = r.dx;
  182.             while (*ptr != '$')
  183.             {
  184.                 buff[ 0] = *ptr++;
  185.                 text (buff);
  186.             }
  187.             break;
  188.         }
  189.  
  190.         case 0x40: /* function 40 (write to file handle) */
  191.             /* write to stdout or stderr? */
  192.             if (r.bx == 1 || r.bx == 2)
  193.             {
  194.                 FP_SEG (ptr) = r.ds;
  195.                 FP_OFF (ptr) = r.dx;
  196.                 r.ax = r.cx;
  197.                 while (r.cx-- > 0)
  198.                 {
  199.                     buff[ 0] = *ptr++;
  200.                     text (buff);
  201.                 }
  202.                 r.cx = r.ax;
  203.                 r.flgs = 0;
  204.             }
  205.             else
  206.             {
  207.                 _chain_intr (int21_vector);
  208.             }
  209.             break;
  210.  
  211.         default: /* call original int21_vector */
  212.             _chain_intr (int21_vector);
  213.             break;
  214.     }
  215. }
  216.  
  217. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  218. //  Function....: get_video_address
  219. //  Author......: Peter Birch
  220. //  Date Created: Thu  08-15-1991
  221. //  Description.: get the video board type from the BIOS
  222. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  223.  
  224. ulong get_video_address (void)
  225. {
  226.     uint    rv;
  227.  
  228.     _asm
  229.     {
  230.         PUSHA
  231.  
  232.         mov     ah, 1ah
  233.         mov     al, 00h
  234.         int     10h
  235.         cmp     al, 1ah         ;true for VGA and MCGA
  236.         jne     short ega
  237.         mov     rv, VGA
  238.         jmp     done
  239.  
  240.     ega: 
  241.         mov     ah, 12h
  242.         mov     bl, 10h
  243.         int     10h
  244.         cmp     bl, 10h         ;false for EGA
  245.         je      short mono
  246.         mov     rv, EGA
  247.         jmp     done
  248.  
  249.     mono: 
  250.         mov     ah, 0fh
  251.         int     10h
  252.         cmp     al, 07h         ;true for MONO
  253.         jne     short cga
  254.         mov     rv, MDA
  255.         jmp     short done
  256.  
  257.     cga: 
  258.         mov     rv, CGA         ;all that is left is CGA
  259.  
  260.     done:
  261.         ;over ride everything now and check for mode, not board
  262.         mov     ah,0fh          ;what video mode are we
  263.         int     10h
  264.         cmp     al,07           ;in mono mode?
  265.         jne     short finish
  266.         mov     rv,MDA
  267.  
  268.     finish:
  269.         POPA
  270.     }
  271.  
  272.     switch (rv)
  273.     {
  274.         case VGA:
  275.         case EGA:
  276.         case CGA:
  277.             return (0xb8000000L);           /* color */
  278.             break;
  279.         default:
  280.             return (0xb0000000L);           /* mono */
  281.     }
  282. }
  283.  
  284. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  285. //  Function....: text
  286. //  Author......: Peter Birch
  287. //  Date Created: Thu  08-15-1991
  288. //  Description.:
  289. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  290.  
  291. void text (char *ptr)
  292. {
  293.     while (*ptr)
  294.     {
  295.         switch (*ptr)
  296.         {
  297.             case '\r':
  298.                 col = left;
  299.                 break;
  300.  
  301.             case '\n':
  302.                 if (++row > bottom)
  303.                 {
  304.                     row = bottom;
  305.                     scroll(1);
  306.                 }
  307.                 break;
  308.  
  309.             case '\t':
  310.                 col += 8;
  311.                 break;
  312.  
  313.             default:
  314.                 if (col > right)
  315.                 {
  316.                     if (wrap)
  317.                     {
  318.                         col = left;
  319.                         if (++row > bottom)
  320.                         {
  321.                             row = bottom;
  322.                             scroll(1);
  323.                          }
  324.                     }
  325.                     else
  326.                         break;
  327.                 }
  328.                 *(screen_ptr+(row * 160)+(col * 2)) = *ptr;
  329.                 ++col;
  330.                 break;
  331.         }
  332.  
  333.         ++ptr;
  334.     }
  335. }
  336.  
  337. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  338. //  Function....: usage
  339. //  Author......: Peter Birch
  340. //  Date Created: Thu  08-15-1991
  341. //  Description.:
  342. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  343.  
  344. void usage (void)
  345. {
  346.     scroll(0);
  347.     row = 24;
  348.     text ("\r\nSyntax: redirect [/cn] [/w] top left bottom right command [param1 param2 ...]");
  349.     text ("\r\n       /cn where n is a number from 1 to 255, white on black would be /c7");
  350.     text ("\r\n       /w to wrap long lines instead of truncating them.");
  351.     exit (1);
  352. }
  353.  
  354. //█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  355. //  Function....: scroll
  356. //  Author......: Peter Birch
  357. //  Date Created: Thu  08-15-1991
  358. //  Description.:
  359. //█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
  360.  
  361. void scroll (uchar lines)
  362. {
  363.    /* scroll screen up lines number of lines, 0 = clear screen */
  364.     _asm
  365.     {
  366.         PUSHA
  367.         mov     ah,6            ;scroll up
  368.         mov     al,lines        ;lines to scroll
  369.         mov     bh,color        ;attribute to blank area to
  370.         mov     ch,top
  371.         mov     cl,left
  372.         mov     dh,bottom
  373.         mov     dl,right
  374.         int     10h
  375.         POPA
  376.     }
  377. }
  378. /* eof:redirect */
  379.