home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 (jgd@dixie.com)
- * 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 <stdio.h>
- #include <dos.h>
-
- /***** 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. (jgd@dixie.com)\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 <port_address data> Arguments are in hex\n");
- printf("\nCommands:\n");
- printf(" \n");
- printf("r read the port\n");
- printf("w write the port\n");
- printf("e<xd> Enter a byte (word in designated mode, hex or decimal)\n");
- printf("m<xdbw> Mode (x=hex, d=dec, b=byte, w=word)\n");
- printf("t n Toggle bit <n>\n");
- printf("c Clear all bits\n");
- printf("s Set all bits\n");
- printf("p Set port address\n");
- printf("g<io> 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, <t> 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, <t> to toggle between\n");
- printf("output byte and 0000. Hit <enter> to stop. ");
- } else {
- printf("\nContinuous input - hit <enter> 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 **********************************/
-