Category : Assembly Language Source Code
Archive   : PORT11.ZIP
Filename : PORT.C

 
Output of file : PORT.C contained in archive : PORT11.ZIP
/*
* Port - Do all kinds of wild and crazy things to PC I/O ports
*
* Rev 1.1 03/13/91
* John De Armond, Rapid Deployment Systems ([email protected])
* Copyright 1991, John De Armond, Minimal Rights Reserved
*
* Compiled with the supplied project file under Borland C++ 2.0 but
* otherwise uncontaminated with C++ drool.
*
* Edited with MKS vi. To align indents, set tabstop=4, shiftwidth=4
*
* Surgeon General's warning: Caution: Misuse or abuse of this
* program is dangerous to the health of
* your hard disk, your memory, your video
* monitor and other such goodies. Govern
* your actions accordingly.
*/

#include
#include

/***** define a few symbolic constants */
#define BYTE 1
#define WORD 2
#define HEX 3
#define DEC 4
#define IN 5
#define OUT 6
/***************************************/

unsigned int port=0, byte=0;
unsigned int save_port, save_byte;
char buf[80];
int entry_mode = HEX;
int byte_mode = BYTE;
int io_mode = OUT;
int quiet=0;
int match_byte;

extern char * token();
char *token_ptr;
int is_a_tty = 0;
int echo_command = 0;

main(argc,argv)
int argc;
char **argv;
{
unsigned int gak;
FILE *fp;

/* yes, I do mean "=" below */
if ( !(is_a_tty = isatty(0)) ) { /* check stdin for source */
echo_command=1; /* if we're on a pipe, echo each
command */
}

if (argc >= 2) { /* if only 2, then argv[1] is port number in hex */
sscanf(argv[1],"%x",&port);
}
if (argc >=3) { /* if 3 arguments, then argv[2] is the bit pattern*/
sscanf(argv[2],"%x",&byte);
}

printf("PORT v1.1 03/13/91 by John De Armond. ([email protected])\n");

help();

for (;;) {
prompt();

/* this little trick allows us to redirect a file in and
then take keyboard input. This allows configuration files
to be piped in.
*/
if (fgets(buf,78,stdin) == NULL) { /* when we hit end of file, */
freopen("con", "r",stdin); /* open the console */
is_a_tty = 1;
echo_command=0;
continue;
}

if (echo_command) {
printf("cmd:%s",buf);
}
switch (buf[0]) {

case 'r': /* read port */
if (strlen(buf) >2) { /* we have a wait specification */
token(&buf[1]);
if (token_ptr != NULL) { /* if pattern specified */
sscanf(token_ptr,"%x",&match_byte);
printf(
"Waiting for byte %4.4x. Hit any key to terminate\n");
read_port();
while (!kbhit()) {
save_byte=byte;
read_port();
if (byte == match_byte) {
printf("Pattern %4.4x found, hit any key.\n",byte);
byte=save_byte;
break;
}
byte=save_byte;
} /* while */
getch(); /* clears the port */
} /* if token_ptr */
} else {
read_port();
}
break;

case 'w': /* write port */
if (strlen(buf) >2) { /* we have a wait specification */
token(&buf[1]);
if (token_ptr != NULL) { /* if pattern specified */
sscanf(token_ptr,"%x",&match_byte);
printf(
"Waiting for byte %4.4x. Hit any key to terminate\n",
match_byte);
write_port();
while (!kbhit()) {
save_byte=byte;
read_port();
if (byte == match_byte) {
printf("Pattern %4.4x found, hit any key.\n",byte);
byte=save_byte;
break;
}
byte=save_byte;

} /* while */
getch(); /* clears the port */
} /* if token_ptr */
} else {
write_port();
}
break;

case 'e': /* enter byte in default mode */
switch (buf[1]) {
case 'x': /* enter byte in hex mode*/
token(&buf[2]);
gak=0;
sscanf(token_ptr, "%x",&gak);
byte = gak;
entry_mode=HEX;
break;
case 'd': /* enter byte in decimal mode*/
token(&buf[2]);
gak=0;
sscanf(token_ptr, "%u",&gak);
byte = gak;
entry_mode=DEC;
break;
default: /* use the default mode */
token(&buf[2]);
gak=0;
if (entry_mode == HEX)
sscanf(token_ptr, "%x",&gak);
else
sscanf(token_ptr, "%u",&gak);
byte = gak;
break;

}
break;

case 't': /* toggle designated bit */
if (buf[1] == 'a') {
byte = ~ byte; /* special case, flip all bits */
break;
}

token(&buf[1]);
sscanf(token_ptr, "%d", &gak);
toggle_bit(gak);
break;

case 'i':
port++;
break;

case 'd':
port--;
break;

case 'm': /* set entry mode, hex, dec, byte, word */
switch (buf[1]) {
case 'x':
entry_mode = HEX;
break;
case 'd':
entry_mode = DEC;
break;
case 'b':
byte_mode = BYTE;
break;
case 'w':
byte_mode = WORD;
break;
case '\0': /* nothing entered */
default:
break;
}
break;

case 'c': /* clear all bits */
byte = 0;
break;
case 's': /* set all bits */
byte = ~0;
break;
case 'p': /* set port address */
token(&buf[1]);
if (entry_mode == HEX)
sscanf(token_ptr, "%x",&gak);
else
sscanf(token_ptr, "%u",&gak);
if (gak)
port = gak;
break;

case 'q': /* quit */
puts("");
exit(0);

case 'g': /* go continuously, repeat last I/O op */
switch (buf[1]) {
case 'i': /* input mode */
rep_io(IN);
break;
case 'o':
rep_io(OUT);
break;
default:
puts("Say What???");
break;
}
break;

case '<': /* get commands from a file */
token(&buf[1]);
if ( freopen(token_ptr,"r",stdin) == NULL ) {
printf("Cannot open file\n");
break; /* let the check at the head of the loop */
} /* reopen the console */
is_a_tty=0;
echo_command=1;
break;

case '?': /* show help */
help();
break;
default:
puts("Say What???");
} /* switch buf[0] */
print_it();

} /* for (;;) */

} /* main */

print_it()
{
int i,j;
unsigned int bit;
extern char * to_bin();

if (is_a_tty) {
printf(" Bits\n");
printf(" 5432 1098 7654 3210\n");
}
if (entry_mode == HEX) {
printf("Port: %4.4x Byte: %4.4x, %s ", port, byte, to_bin(byte));
printf("Mode= HEX ");
} else {
printf("Port: %5.5u Byte: %5.5u, %s ", port, byte, to_bin(byte));
printf("Mode= Decimal ");
}
if (byte_mode == BYTE) {
printf("Data= BYTE\n");
} else {
printf("Data= WORD\n");
}
}

/* convert an unsigned int to a binary string */
char *
to_bin(bit)
unsigned int bit;
{

static char string[25];
int i,j;

memset(string,0,25);

/* convert the byte to binary */
for (i=0,j=0; i<16; i++,j++) {
if ( bit & 0x01) {
string[18-j] = '1';
} else {
string[18-j] = '0';
}
if (!((i+1)%4) && i>1)
string[18- ++j] = ' ';

bit = bit >>1;
}

return (string);
}

prompt()
{
if (is_a_tty) {
printf("Command (help-?): ");
}
return;
}

read_port()
{

if (byte_mode == BYTE) {
byte = inportb(port);
} else {
byte = inport(port);
}

return;
}

write_port()
{
if (byte_mode == BYTE) {
outportb(port,byte);
} else {
outport(port,byte);
}
return;

}

help()
{
printf("\nUsage: port Arguments are in hex\n");
printf("\nCommands:\n");
printf(" \n");
printf("r read the port\n");
printf("w write the port\n");
printf("e Enter a byte (word in designated mode, hex or decimal)\n");
printf("m Mode (x=hex, d=dec, b=byte, w=word)\n");
printf("t n Toggle bit \n");
printf("c Clear all bits\n");
printf("s Set all bits\n");
printf("p Set port address\n");
printf("g Go In or Go Out - perform action continuously\n");
printf("i Increment port address one count\n");
printf("d Decrement port address one count\n");
printf("q Quit\n");
printf("< Redirect commands from a file\n");
printf("? Help\n\n");
printf("While in \"go out\" mode, keys 0-f will toggle bits, will cause the output\n");
printf("to alternate between the byte pattern and all zeros.\n\n");
}

/****************************************************************************/
/* token takes a string passed in x and stores the next token in the global */
/* variable token_ptr. */
/* The function returns a pointer to the next character past the end of */
/* the token */
/****************************************************************************/

#define WHITESPACE 1
#define TOKEN 2
char *
token(x)
char *x;
{
int state = WHITESPACE;
static char *pointer;

pointer = (char *) NULL;

while (*x != (char) NULL) {
switch (*x) {
case ' ':
case '\x09': /* tab */
if (state == TOKEN) {
*x = '\x0'; /* null terminate */
token_ptr=pointer; /* point to beginning of this token */
return(++x);
} else {
++x; /* skip this character */
state = WHITESPACE;
}
break;

case '\n':
*x = '\x0'; /* null terminate return string */
token_ptr = pointer;
return((char *) 0);
default: /* this must be a token */
if (state == WHITESPACE) {
pointer=x++; /* set pointer to start of token */
state=TOKEN;
} else {
x++;
state=TOKEN;
}
break;
} /* switch */

} /* while */

if (state == TOKEN) {
*x = '\x0';
token_ptr = pointer;
return ( (char *) NULL);
} else {
token_ptr = (char *) NULL;
return ( (char *) NULL);
}
}

rep_io(x)
int x; /* mode, input or output */
{
unsigned int i;
char str[20];
int inp;
int toggle = 0;
unsigned int tmp_byte;
int old_byte;
int dirty;

toggle = 0;
i = 0;
old_byte=0;
dirty=0;

if (x == OUT) {
printf(
"\nContinuous output - Press keys 0-f to toggle bits, to toggle between\n");
printf("output byte and 0000. Hit to stop. ");
} else {
printf("\nContinuous input - hit to stop. ");
}
printf("\"<\" and \">\" changes port address\n");
printf("Hit any other key to update screen.\n\n");


if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}

printf("Port = %s\n", str);
showit(x,i,toggle);

for ( ;; ) {

if (kbhit() ) { /* if keyboard input, process to toggle bits */
inp = getch();
switch (inp) {
case '\n':
case '\r':
puts(" ");
return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (x == OUT)
toggle_bit(inp-'0');
dirty = ~dirty;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
if (x == OUT)
toggle_bit(inp - 'a' + 10);
dirty = ~dirty;
break;
case 't': /* toggle between outputing byte and 0000 */
if (x == OUT) {
toggle = ~toggle;
showit(x,i,toggle);
}
break;
case '<':
port--;
if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}

printf(" Port = %s\n", str);
showit(x,i,toggle);
break;

case '>':
port++;
if (entry_mode == HEX) {
sprintf(str,"%4.4x",port);
} else {
sprintf(str,"%5.5u",port);
}

printf(" Port = %s\n", str);
showit(x,i,toggle);
break;

default: /* any other key updates the screen */
showit(x,i,toggle);
break;
}
} /* if */

/* actually do the port thang */
if (x == IN) {
old_byte = byte;
read_port();
if (old_byte != byte)
showit(x,i,toggle);

} else { /* output mode */
if (dirty) {
dirty = ~dirty;
showit(x,i,toggle);
}

/* if toggle specified, then alternate between the byte and
all 0000 */
if (toggle) {
if (i%2) {
tmp_byte = byte;
byte = 0;
write_port();
byte = tmp_byte;
} else {
write_port();
}
} else { /* if not toggle */
write_port();
}
}
i++;
}
}

/* this routine toggles a specified bit in the global variable byte */
toggle_bit(x)
{
unsigned int bits[] = {
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80,
0x100,
0x200,
0x400,
0x800,
0x1000,
0x2000,
0x4000,
0x8000,
};

byte = byte ^ bits[x%16];
return;
}

/* update screen during continuous output or input */
showit(x,i,toggle)
int x;
int i;
int toggle;
{
extern char * to_bin();

if (x == IN) {
if (entry_mode == HEX) {
printf("\rRead loop:%5.5u, value = %4.4x, %s", i,byte,to_bin(byte));
} else {
printf("\rRead loop:%5.5u, value = %5.5u, %s", i,byte,to_bin(byte));
}
} else {
if (entry_mode == HEX) {
printf("\rWrite loop:%5.5u, value = %4.4x, %s", i,byte,to_bin(byte));
} else {
printf("\rWrite loop:%5.5u, value = %5.5u, %s", i,byte,to_bin(byte));
}

if (toggle) {
printf(" toggling");
} else {
printf(" ");
}
}
return;
}
/************************** end of file **********************************/


  3 Responses to “Category : Assembly Language Source Code
Archive   : PORT11.ZIP
Filename : PORT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/