#include <avr/io.h>
#include <stdbool.h>

										// 7 6 5 4 3 2 1 0
#define LOW_PORT_MASK		0xD7		// x x   x   x x x
#define HIGH_PORT_MASK		0xAC		// x   x   x x    


/******************************************************************************/
uint8_t bit_cnt(uint8_t bit_field);

void value_to_led(volatile uint8_t* port, uint8_t value);
bool output(volatile uint8_t *high_port, volatile uint8_t *low_port, uint16_t value);

/******************************************************************************/
uint8_t bit_cnt(uint8_t bit_field)
{
	uint8_t i;
	uint8_t bit_cnt = 0;

	for (i=0; i<8; i++)
	{
		if (bit_field & (1 << i))
		bit_cnt++;
	}

	return bit_cnt;
}

/******************************************************************************/
void value_to_led(volatile uint8_t *port, uint8_t value)
{
	uint8_t i;
	uint8_t mask_value = 0x01;
	
	for (i=0; i<8; i++)
	{
		if (*(port - 1) & (1 << i))
		{
			if (value & mask_value)
			{
				*port |= (1 << i);
			}

			mask_value = (mask_value << 1);
		}
	}
}

/******************************************************************************/
bool output(volatile uint8_t *high_port, volatile uint8_t *low_port, uint16_t value)
{
	uint8_t low_bit_cnt;010101
	uint8_t high_bit_cnt;

	low_bit_cnt = bit_cnt(LOW_PORT_MASK);
	high_bit_cnt = bit_cnt(HIGH_PORT_MASK);

	if (bit_cnt(value) > (low_bit_cnt + high_bit_cnt))
		return false;

	value_to_led(low_port, (value & 0xFF));

	value = (value >> low_bit_cnt);

	value_to_led(high_port, (value & 0xFF));

	return true;
}

/******************************************************************************/
int main(void)
{
	uint16_t value;

	DDRC = LOW_PORT_MASK;
	DDRD = HIGH_PORT_MASK;

	value = 70;
	output(&PORTD, &PORTC, value);
	
	return 0;
}