//----------------------------------------------
// hello.cpp - This is a C++ version of our 
//	original hello.asm example program.
// Author: 	M. Frank
// Date:	10/6/04
//----------------------------------------------

// Here are some control registers that we need.
static unsigned char * const CONFIG_BASE = (unsigned char *)0x1000;     // Base address of control register region.
static unsigned char 
	* const BAUD  = CONFIG_BASE + 0x2b,  // SCI baud rate control register.
	* const SCCR1 = CONFIG_BASE + 0x2c,  // Serial Communication Control Register 1.
	* const SCCR2 = CONFIG_BASE + 0x2d,  // Serial Communication Control Register 2.
	* const SCSR  = CONFIG_BASE + 0x2e,  // Serial Communication Status Register.
	* const SCDAT = CONFIG_BASE + 0x2f;  // Serial Communication DATa register.
	
// Masks for specific bit positions.
static const unsigned char 
	BIT0 = 1<<0, BIT1 = 1<<1, BIT2 = 1<<2, BIT3 = 1<<3,
	BIT4 = 1<<4, BIT5 = 1<<5, BIT6 = 1<<6, BIT7 = 1<<7;
	
// Particular control register bits of interest.
static const unsigned char
	// These control bits are in control register BAUD.
	SCP1 = BIT5,	// Serial Comm. baud rate Prescaler select bits.
	SCP0 = BIT4,	// "
	// These control bits are in control register SCCR2.
	TE = BIT3, 	// Transmit Enable for SCI.
	RE = BIT2,	// Receive Enable for SCI.
	// These control bits are in control register SCSR.
	TDRE = BIT7;	// Transmit Data Register Empty flag.

// Turn on & initialize the Serial Communication Interface.
void onsci() {
	*BAUD = SCP1|SCP0;	// Sets SCI to 9600 baud (actually 9615) given a 2 MHz bus clock.
	*SCCR1 = 0;		// Selects normal "8 data bit, 1 stop bit, no flow control" communication.
	*SCCR2 = TE|RE;		// Enable transmit and receive.
}

// Output a character to the SCI.
void output(const char a) {
	while (!(*SCSR&TDRE)) {}	// Wait for Transmit Data Register Empty in Ser. Comm. Status Reg.
	*SCDAT = a&~BIT7;	// Send byte using "no parity" communication; so clear parity bit (bit 7).
}

// Output a carriage-return linefeed sequence to the SCI.
void outcrlf() {
	output('\r');	// output carriage Return = CR = ASCII $0a
	output('\n');	// output linefeed, LF (Newline, NL) = ASCII $0d
}

// Output a text string to the SCI.
void outstrg(const char *pString) {
	while (*pString != '\x04') {	// Until End Of Tranmission, EOT = ASCII $04
		output(*pString++);	// output the present character and go to next.
	}
}

int main() {
	onsci();	// Initialize the Serial Communication Interface.
	outstrg("Hello World\x04");
	outcrlf();
	for(int i='0'; i<='9'; i++) 
		output(i);
	return 0;
}
