#include <stdio.h>
#include <stdlib.h>
#include <asm/types.h>
#include <unistd.h>
//#include <asm/io.h>
#include <sys/io.h>

#define LP_BASE 0x3bc

#define	SLIN_BAR  0x08
#define	RESET_BAR 0x04
#define	STB_BAR   0x01

void printChar(const char portdata);

int main(int argc, char **argv) {

//	__u8 portdata;
	char *cPtr;

	if(argc < 2) {
		fprintf(stderr, "Must supply a value to send to port...\n");
		exit(1);
	}

	/* let us know the value of portdata */
//	printf("Value submitted for sending to hardware: %i\n", portdata);

	/* attempt to reserve region in io space */
	if(ioperm(LP_BASE, 3, 1) < 0) {
		fprintf(stderr, "Cannot reserve region in io space, aborting...\n");
		exit(1);
	}

	/*
	** 
	*/

	cPtr = argv[1];

	while(*cPtr) {
		printChar(*cPtr);
		cPtr++;
	}
	printChar((char)0x0D);
	printChar((char)0x0A);

	/* attempt to release reserved region in io space */
	if(ioperm(LP_BASE, 3, 0) < 0) {
		fprintf(stderr, "Cannot release region in io space, aborting...\n");
		exit(1);
	}

	return(0);  /* just to be nice ;) */

}
void printChar(const char portdata){
	__u8 controlByte;
	controlByte = inb(LP_BASE+2);
	outb(controlByte | SLIN_BAR | RESET_BAR, LP_BASE+2);

	/* send data byte to io port */
	outb(portdata, LP_BASE);

	/*
	** While the BUSY input line is set
	**   display dots on the console
	** end while
	** Toggle the data byte
	*/
	while( (inb(LP_BASE+1) & 0x0080) == 0) {
//		printf("1");
	}
	outb(controlByte | SLIN_BAR | RESET_BAR | STB_BAR, LP_BASE+2);
	outb(controlByte | SLIN_BAR | RESET_BAR | STB_BAR, LP_BASE+2);
//	printf("Control port: 0x%04X=0x%02X\n", LP_BASE+2,
//	  controlByte | SLIN_BAR | RESET_BAR | STB_BAR);
	outb(controlByte | SLIN_BAR | RESET_BAR, LP_BASE+2);
//	printf("Control port: 0x%04X=0x%02X\n", LP_BASE+2,
//	  controlByte | SLIN_BAR | RESET_BAR);
}
