//Filename: util.cpp
//Purpose: A number of utility functions, for converting from binary to decimal
//   and back again.
//$Id: util.c,v 1.4 1997/07/29 21:11:23 rkirkpat Exp $

/*
 * Copyright (c) 1996-1997 by Ryan Kirkpatrick (rkirkpat@nag.cs.colorado.edu). 
 *   All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */ 

#include "util.h"

int bin2dec (char *bin)
//PRE: bin points to a eight or less character string.
//POST: FCTVAL == decimal equivalent of bin. Missing leading places in bin 
//        filled with zeros before conversion. Then LSB was in bin[7], and 
//        MSB was in bin[0].
{
	int temp = 0;
	int j = strlen(bin) - 1;

	//Loop through binary number, building decimal number.
	int i;
	for (i = 0; i < strlen(bin); i++)
	{
		if (bin[i] == '1')
			temp += (int)pow(2,j);
		j--;
	}

	return temp;
}

char* dec2bin (int dec)
//PRE: dec is less than 256 and greater than zero.
//POST: FCTVAL == string of one and zeros representing the 8bit binary 
//        equivlent of dec. LSB is in FCTVAL[7], MSB is in FCTVAL[0].
{
	char* temp = (char*)calloc(9,sizeof(char));
	char* out = (char*)calloc(9,sizeof(char));
	int i = 0;
	int j;

	//Continous divide by two to create binary number in reverse.
	while (dec != 0)
	{
		if (dec % 2 == 1)
			temp[i] = '1';
		else
			temp[i] = '0';
		dec = dec / 2;
		i++;
	}

	//Correct count of binary digits
	i--;

	//Pad the start of string if needed
	for (j = 0; j < 7 - i; j++)
		out[j] = '0';

	//Reverse order of binary number
	for (j = 7 - i; j < 8; j++)
	{
		out[j] = temp[i];
		i--;
	}

	return out;
}

int moddec (int dec, int pos)
//PRE: dec is less than 256, pos is less than 8 (both greater than zero).
//POST: The pos(th) bit of dec has been toggled. ie: 10d => 1010b => 1011b
//        => 11d if pos was 0.
{
	int temp;
	char *str;

	//Convert dec to bin.
	str = dec2bin(dec);

	//Flip appropriate bit.
	if (str[7-pos] == '0')
		str[7-pos] = '1';
	else
		str[7-pos] = '0';

	//Convert from bin back to dec.
	temp = bin2dec(str);

	free(str);

	return temp;
}

int setdec (int dec, int pos, int state)
//PRE: dec is less than 256, pos is less than 8, state is less than 2, and
//       all are greater than zero.
//POST: The pos(th) bit of dec has been set to state. ie: 10d => 1010b
//        => 1000b => 8d if pos was 2 and state was 0.
{
	int temp;
	char *str;

	//Convert dec to bin.
	str = dec2bin(dec);

	//Set appropriate bit.
	if (state == 1)
		str[7-pos] = '1';
	else
		str[7-pos] = '0';

	//Convert from bin back to dec.
	temp = bin2dec(str);

	free(str);

	return temp;
}
	
int dec2bcd (int dec)
//PRE: dec is less than 100 and greater than zero
//POST: FCTVAL is a decimal, that when broken down into binary, seperated at
//        between bits 4 and 5, represents two _B_inary _C_oded _D_ecimals.
{
	//Seperate tens from ones.
	int tens = dec / 10;
	int ones = dec % 10;

	int temp;
	char *btens;
	char *bones;
	char *bcd = (char*)calloc(9,sizeof(char));
	int i = 0;
	int j;

	//Convert tens and ones to binary.
	btens = dec2bin(tens);
	bones = dec2bin(ones);

	//Copy the last four digits of tens binary first, then the last
	//  four digits of ones binary second.
	for (j = 4; j < 8; j++)
	{
		bcd[i] = btens[j];
		i++;
	}
	for (j = 4; j < 8; j++)
	{
		bcd[i] = bones[j];
		i++;
	}
	
	//Convert from binary back to decimal.
	temp = bin2dec(bcd);

	free(bcd);
	free(btens);
	free(bones);

	return temp;
}

//EOF
