#include "io686.h"
#include <conio.h>
#include <math.h>

#define ledbase 0x300
#define initword 0xFF


/* Class LEDPort
*/
LEDPort::LEDPort() {
	m_data = initword;
	_outp(ledbase,m_data);			//SLUKKER ALLE LEDS
}

LEDPort::LEDPort(unsigned char data) {
	m_data = data;
	_outp(ledbase,m_data);
}

LEDPort::~LEDPort(){
	m_data = initword;
	_outp(ledbase,m_data);			//SLUKKER ALLE LEDS
}
void LEDPort::set(unsigned char LEDNr) {	
	m_data &= 0xFF-static_cast<unsigned char>(pow(2,LEDNr));
	_outp(ledbase,m_data);
}

void LEDPort::reset(unsigned char LEDNr) {
	m_data |= static_cast<unsigned char>(pow(2,LEDNr));
	_outp(ledbase,m_data);
}

void LEDPort::toggle(unsigned char LEDNr) {
	m_data ^= static_cast<unsigned char>(pow(2,LEDNr));
	_outp(ledbase,m_data);
}

bool LEDPort::on(unsigned char LEDNr) const {
	return ( !(m_data & static_cast<unsigned char>(pow(2,LEDNr))) );
}

unsigned char LEDPort::status() const {
	return ~m_data;
}

void LEDPort::setall(unsigned char data) {
	this->m_data = ~data;
	_outp(ledbase, this->m_data );
}

/* Class SwitchPort
*/
bool SwitchPort::on(unsigned char switchNr) const {
	return ( ! (_inp(ledbase) & static_cast<unsigned char>(pow(2,switchNr))) );
};


/* Class Timer
*/

#define TIMER_ADR 0x308

Timer::Timer(TimerID id, TimerMode mode) {
	this->m_id = id;
	_outp(TIMER_ADR+3, 0 | (m_id << 6) | 3<<4 | (mode << 1) );
}

Timer::~Timer() {
	_outp(TIMER_ADR+3, 0 | (m_id << 6) | 3<<4 );
}

void Timer::start(unsigned short timervalue) {
	_outp(TIMER_ADR+m_id, (timervalue & 0xFF));
	_outp(TIMER_ADR+m_id, (timervalue>>8) & 0xFF);
}

unsigned short Timer::read() const {
	_outp(TIMER_ADR + 3, (unsigned char)m_id << 6);
	return( (_inp(TIMER_ADR+m_id) ) + (_inp(TIMER_ADR+m_id)<<8));
}


/* Class PPI
*/
PPI::PPI(PortDirection portAdir, PortDirection portBdir, PortDirection portCdir) {
	_outp(0x307,128 | portAdir<<4 | portCdir<<3 | portBdir<<1 | portCdir);
}

void PPI::write(PortID id, unsigned char data) {
	_outp(0x304+id,data);
}

unsigned char PPI::read(PortID id) const {
	return(_inp(0x304+id));
}

