home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HomeWare 14
/
HOMEWARE14.bin
/
prog
/
tee_src.arj
/
REDIRECT.C
next >
Wrap
C/C++ Source or Header
|
1993-06-07
|
10KB
|
379 lines
// This source was last touched on 02/16/91
// and except for some comments it has not changed.
// so parden the bad programming or flaws you might find,
// I have learned _much_ even since since then.
//
// Peter Birch
// 06/07/93
// Microsoft C
// Please do not remove my name from this source
// or charge others for this program, Thank you!
/*
** send all output of a called progam to a user defined window
**
**
** Peter Birch
**
*/
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <graph.h>
#include <stdio.h>
#include <ctype.h>
#include <process.h>
#define VGA 4
#define EGA 3
#define CGA 2
#define MDA 1
typedef struct
{
unsigned es, ds, di, si, bp, sp,
bx, dx, cx, ax, ip, cs,
flgs;
} interrupt_regs;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned char uchar;
/* internal function prototypes */
int main (int argc, char **argv);
void interrupt cdecl _far int21_handler (interrupt_regs r);
ulong get_video_address (void);
void text (char *ptr);
void usage (void);
void scroll (uchar lines);
/* holds character to print */
/* all chars in my functions are printed one at a time */
char buff[ 2] = "\0\0";
char far *ptr,
far *screen_ptr = NULL;
uchar top = 0,
left = 0,
bottom = 24,
right = 79,
row = 0,
col = 0,
color = 7;
int wrap = 0;
void (interrupt cdecl _far *int21_vector)(); /* original int 21 vector owner */
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: main
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.: send all output of a called progam to a user defined window
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
int main (int argc, char **argv)
{
int i;
/* has screen_ptr been initialized? */
if (screen_ptr == NULL)
{
screen_ptr = (char far *)get_video_address();
}
if (argc > 5)
{
/* look for switches, they must be first on the command line. */
i = 1;
while (argv[ i][ 0] == '-' || argv[ i][ 0] == '/')
{
switch (argv[ i][ 1])
{
case 'c': /* color */
case 'C':
color = (uchar)atoi(&(argv[ i][ 2]));
break;
case 'w': /* wrap long lines */
case 'W':
wrap = 1;
break;
default:
usage();
break;
}
++i;
}
/* create window for output */
top = (uchar) atoi (argv[ i++]); /* top */
left = (uchar) atoi (argv[ i++]); /* left */
bottom = (uchar) atoi (argv[ i++]); /* bottom */
right = (uchar) atoi (argv[ i++]); /* right */
col = left;
row = top;
/* clear window */
scroll (0);
/* save old interrupt 21 vector */
int21_vector = _dos_getvect (0x21);
/* set int21 to call my interrupt function */
_dos_setvect (0x21, int21_handler);
/* execute program passed on command line */
spawnvp (P_WAIT, argv[ i], &(argv[ i]));
/* restore int21 handler to original function */
_dos_setvect (0x21, int21_vector);
}
else
{
usage();
}
return (0);
}
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: int21_handler
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.: my int 21 handler
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
void interrupt cdecl _far int21_handler (interrupt_regs r)
{
switch (r.ax >> 8) /* ah */
{
case 0x02: /* function 2 (display character in dl register) */
buff[ 0] = (uchar)(r.dx & 0xff); /* dl */
text (buff);
break;
case 0x06: /* function 6 (direct console i/o) */
/* output requested? */
if ((uchar)(r.dx & 0xff) != 0xff) /* dl */
{
buff[ 0] = (uchar)(r.dx & 0xff); /* dl */
text (buff);
}
else
{
_chain_intr (int21_vector);
}
break;
case 0x09: /* function 9 (print dollar-sign delimited string) */
{
FP_SEG (ptr) = r.ds;
FP_OFF (ptr) = r.dx;
while (*ptr != '$')
{
buff[ 0] = *ptr++;
text (buff);
}
break;
}
case 0x40: /* function 40 (write to file handle) */
/* write to stdout or stderr? */
if (r.bx == 1 || r.bx == 2)
{
FP_SEG (ptr) = r.ds;
FP_OFF (ptr) = r.dx;
r.ax = r.cx;
while (r.cx-- > 0)
{
buff[ 0] = *ptr++;
text (buff);
}
r.cx = r.ax;
r.flgs = 0;
}
else
{
_chain_intr (int21_vector);
}
break;
default: /* call original int21_vector */
_chain_intr (int21_vector);
break;
}
}
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: get_video_address
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.: get the video board type from the BIOS
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
ulong get_video_address (void)
{
uint rv;
_asm
{
PUSHA
mov ah, 1ah
mov al, 00h
int 10h
cmp al, 1ah ;true for VGA and MCGA
jne short ega
mov rv, VGA
jmp done
ega:
mov ah, 12h
mov bl, 10h
int 10h
cmp bl, 10h ;false for EGA
je short mono
mov rv, EGA
jmp done
mono:
mov ah, 0fh
int 10h
cmp al, 07h ;true for MONO
jne short cga
mov rv, MDA
jmp short done
cga:
mov rv, CGA ;all that is left is CGA
done:
;over ride everything now and check for mode, not board
mov ah,0fh ;what video mode are we
int 10h
cmp al,07 ;in mono mode?
jne short finish
mov rv,MDA
finish:
POPA
}
switch (rv)
{
case VGA:
case EGA:
case CGA:
return (0xb8000000L); /* color */
break;
default:
return (0xb0000000L); /* mono */
}
}
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: text
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.:
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
void text (char *ptr)
{
while (*ptr)
{
switch (*ptr)
{
case '\r':
col = left;
break;
case '\n':
if (++row > bottom)
{
row = bottom;
scroll(1);
}
break;
case '\t':
col += 8;
break;
default:
if (col > right)
{
if (wrap)
{
col = left;
if (++row > bottom)
{
row = bottom;
scroll(1);
}
}
else
break;
}
*(screen_ptr+(row * 160)+(col * 2)) = *ptr;
++col;
break;
}
++ptr;
}
}
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: usage
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.:
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
void usage (void)
{
scroll(0);
row = 24;
text ("\r\nSyntax: redirect [/cn] [/w] top left bottom right command [param1 param2 ...]");
text ("\r\n /cn where n is a number from 1 to 255, white on black would be /c7");
text ("\r\n /w to wrap long lines instead of truncating them.");
exit (1);
}
//█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
// Function....: scroll
// Author......: Peter Birch
// Date Created: Thu 08-15-1991
// Description.:
//█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
void scroll (uchar lines)
{
/* scroll screen up lines number of lines, 0 = clear screen */
_asm
{
PUSHA
mov ah,6 ;scroll up
mov al,lines ;lines to scroll
mov bh,color ;attribute to blank area to
mov ch,top
mov cl,left
mov dh,bottom
mov dl,right
int 10h
POPA
}
}
/* eof:redirect */