It displays the input ports and allows the user to send a byte to any of the output ports.
For example, to send a byte to the console, type "out 11h 41h" which will send an "A" to port 11h.
Just a quick-and-dirty tool, useful when troubleshooting or designing a new board.
You can build it with the Aztec C compiler.
- Code: Select all
/* -------------------------------------------------------------------------- */
/* Altair digital I/O Control Panel */
/* */
/* Wayne Parham */
/* */
/* wayne@parhamdata.com */
/* -------------------------------------------------------------------------- */
#include "stdio.h"
int strncasecmp( s1, s2, length ) /* String comparison */
char* s1;
char* s2;
int length;
{
char* c1 = s1;
char* c2 = s2;
int l = 0;
int r = 0;
while( (r == 0) && (l < length) && (*c2 != '\0') ) {
r = *c1 - *c2;
c1++;
c2++;
l++;
}
return( r );
}
int hex2decimal( hex ) /* Convert a hex number to a decimal number */
char* hex;
{
int decimal = 0;
int length = 0;
int value = 0;
int base = 1;
int i = 0;
length = strlen( hex );
for( i = length--; i >= 0; i-- )
{
if( hex[i] >= '0' && hex[i] <= '9' )
{
decimal += (hex[i] - 48) * base;
base *= 16;
}
else if( hex[i] >= 'A' && hex[i] <= 'F' )
{
decimal += (hex[i] - 55) * base;
base *= 16;
}
else if( hex[i] >= 'a' && hex[i] <= 'f' )
{
decimal += (hex[i] - 87) * base;
base *= 16;
}
}
return( decimal );
}
int interpretNumber( number ) /* Determine if value is decimal or hex */
char* number;
{
int lcp;
int value;
char lastChar;
lcp = strlen( number ) - 1;
lastChar = number[lcp];
if( lastChar == 'H' || lastChar == 'h' ) {
number[lcp] = '\0';
value = hex2decimal( number );
} else {
value = (unsigned char) atoi( number );
}
return( value );
}
char* cleanString( string ) /* Replace space with null */
char* string; /* to isolate first argument */
{
int p;
int l;
l = strlen( string );
for( p = 0; p < l; p++ ) {
if( string[p] == ' ' ) {
string[p] = '\0';
}
}
return( string );
}
void outPort( portdata ) /* Send data to I/O port */
char* portdata;
{
unsigned char port;
unsigned char data;
char* op;
char* dp;
port = '\0';
data = '\0';
if( portdata ) {
op = portdata;
if ( op ) {
if( op[0] == ' ' ) {
op++; /* remove leading space */
}
dp = index ( op, ' ' );
if ( dp ) {
if( dp[0] == ' ' ) {
dp++; /* remove leading space */
}
op = cleanString( op );
port = interpretNumber( op );
data = interpretNumber( dp );
printf ( "\nPort %d (%02xH) output -> %d (%02xH)\n\n", port, port, data, data );
out ( port, data );
} else {
printf ( "\nInvalid out command\n\n" );
}
} else {
printf ( "\nInvalid out command\n\n" );
}
}
}
void clearScreen() { /* Scroll 25 lines */
int l;
putchar ( '\r' );
for ( l = 0; l < 25; l++ ) {
putchar ( '\n' );
}
}
int main() {
unsigned char port;
unsigned char data;
unsigned char val;
int showdata;
int offset;
int going;
int instr;
int start;
int end;
int top;
int cls;
int l;
int v;
char* pd;
char cmd[20];
val = '\0';
cmd[0] = '\0';
showdata = 0;
going = 1;
instr = 1;
start = 0;
cls = 1;
end = 16;
top = 127;
offset = 0;
l = 0;
v = 1;
while ( going ) {
if ( cls ) {
clearScreen();
}
if ( showdata ) {
cls = 1;
puts ("================================= Input Data ==================================");
while ( start < top ) {
for ( l = start; l < end; l++ ) {
data = in( l );
printf( "P0%02x", l );
if ( l < (end - 1) ) {
printf( " " );
}
}
printf( "\n\r" );
printf( " " );
for ( l = start; l < end; l++ ) {
data = in( l );
printf( "%02x", data );
if ( l < (end - 1) ) {
printf( " " );
}
}
printf( "\n\r" );
start += 16;
end += 16;
}
puts ("===============================================================================");
}
if ( instr ) {
cls = 1;
puts ("===============================================================================");
puts ("The Intel 8080 processor provides 256 addresses for input and output devices.");
puts ("This program exposes all I/O addresses, allowing you to see the data placed");
puts ("onto each of the ports. You can also send a byte out any of the I/O port");
puts ("addresses. Of course, if there is no hardware addressed on a port, then data");
puts ("read will be undetermined. Data written to an unused port will have no effect.");
puts (" ");
puts ("Available commands are help, show, view, out and quit. Help shows this");
puts ("message. Quit ends the program. Show and view do the same thing, showing the");
puts ("top or bottom 128 input ports. One argument is expected on the show or view");
puts ("command - either \"high\" or \"low\" - which can be abbreviated. ");
puts (" ");
puts ("The out command requires two arguments, first the port number and second, the");
puts ("data that will be presented to the port. Both arguments are expected to be");
puts ("one byte wide, e.g. 0 to 255. Numeric arguments can be either decimal or");
puts ("hexadecimal. Hex values are indicated by a trailing \"H\" character, which must");
puts ("be present even if some digits are alpha characters. ");
puts ("===============================================================================");
}
printf ("\nCommand: ");
fgets ( cmd, sizeof(cmd)-1, stdin );
cmd[strlen(cmd)-1] = '\0';
if ( strncasecmp(cmd, "quit", 4) == 0 ) {
going = 0;
}
else if ( strncasecmp(cmd, "help", 4) == 0 ) {
showdata = 0;
instr = 1;
}
else if ( strncasecmp(cmd, "show h", 6) == 0 ) {
showdata = 1;
instr = 0;
v = 0;
}
else if ( strncasecmp(cmd, "show l", 6) == 0 ) {
showdata = 1;
instr = 0;
v = 1;
}
else if ( strncasecmp(cmd, "view h", 6) == 0 ) {
showdata = 1;
v = 0;
}
else if ( strncasecmp(cmd, "view l", 6) == 0 ) {
showdata = 1;
v = 1;
}
else if ( strncasecmp(cmd, "out", 3) == 0 ) {
showdata = 0;
instr = 0;
cls = 0;
pd = index ( cmd, ' ' );
outPort( pd );
}
if ( v ) {
start = 0; /* view bottom 128 input ports */
end = 16;
top = 127;
} else { /* view top 128 input ports */
start = 128;
end = 144;
top = 255;
}
}
puts ("\n\nEnjoy your day!\n\n");
return 0;
}