// ---------------------------------------------------------------------------------------------------------------------
// Gabriel Malone / Week 3 / Lab 3 / CS 210
// ---------------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// function prototypes // ----------------------------------------------------------------------------------------------
unsigned short reverse_bytes(unsigned short);
unsigned short booths_algorithm(uint8_t, uint8_t);
unsigned int reverse_words(unsigned int);
unsigned int ascii_to_integer(char*, int size);
void to_upper(char*, int size);
void to_lower(char*, int size);
unsigned short full_adder(uint8_t, uint8_t);
char* to_bits(unsigned int);
void print_bits(char*);
void print_string(char*, int);
// ---------------------------------------------------------------------------------------------------------------------
// MAIN
// ---------------------------------------------------------------------------------------------------------------------
int main(int argc, char** argv){
// ---------------------------------------------------------------------------------------------------------------------
// CONVERTING ASCII TO INTEGER DEMO
// -----------------------------------------------------------------------------------------------------------------
char ascii_number [] = "123456"; // c style string as pointer to char (array)
printf("%d", ascii_to_integer
(ascii_number
, 6)); // -----------------------------------------------------------------------------------------------------------------
// CONVERTING LOWER TO UPPERCASE DEMO
// -----------------------------------------------------------------------------------------------------------------
char strA [] = "abcdefg";
to_upper(strA, 7);
print_string(strA, 7);
// -----------------------------------------------------------------------------------------------------------------
// CONVERTING UPPER TO LOWER DEMO
// -----------------------------------------------------------------------------------------------------------------
char strB [] = "GOOBERT";
to_lower(strB, 7);
print_string(strB, 7);
// -----------------------------------------------------------------------------------------------------------------
// REVERSING WORDS DEMO
// -----------------------------------------------------------------------------------------------------------------
printf("\ndword reversed: %X\n",reverse_words
(0xABCDEF00)); // -----------------------------------------------------------------------------------------------------------------
// REVERSING BYTES DEMO
// -----------------------------------------------------------------------------------------------------------------
printf("short word reversed: %X\n",reverse_bytes
(0xABCD)); // -----------------------------------------------------------------------------------------------------------------
// PRINTING BITS DEMO
// -----------------------------------------------------------------------------------------------------------------
print_bits(to_bits(19)); // enter any number up to 32 bits
// -----------------------------------------------------------------------------------------------------------------
// FULL ADDER DEMO
// -----------------------------------------------------------------------------------------------------------------
printf("\n%d",full_adder
(11,255)); // -----------------------------------------------------------------------------------------------------------------
// BOOTHS DEMO
// -----------------------------------------------------------------------------------------------------------------
printf("\n%d", booths_algorithm
(100,12));
}
// ---------------------------------------------------------------------------------------------------------------------
// METHODS
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
unsigned int reverse_words(unsigned int dword){
// -----------------------------------------------------------------------------------------------------------------
return ( (dword & 0x0000FFFF) << 16) + ( (dword & 0xFFFF0000) >> 16); // dword & LO mask << to HO pos and vice-versa
}
// ---------------------------------------------------------------------------------------------------------------------
unsigned short reverse_bytes(unsigned short word){
// -----------------------------------------------------------------------------------------------------------------
return ( (word & 0x00FF) << 8) + ( (word & 0xFF00) >> 8); // word & LO mask << to HO pos and vice-versa
}
// ---------------------------------------------------------------------------------------------------------------------
unsigned short booths_algorithm(uint8_t mcnd, uint8_t mplr){
// -----------------------------------------------------------------------------------------------------------------
unsigned short itr = 0, PB = 0, CB = mplr & 1, LO = mplr, HO=0,product = 0x0000, phb;
while (itr ++ < 8) // need to loop for 8 bits
{
if (CB ^ PB) // if xor results in true
{ // add multiplicand to the HO byte
if (CB) HO = full_adder(HO, full_adder(~mcnd, 1)); // twos compliment addition for subtraction
if (PB) HO = full_adder(HO, mcnd); // addition
}
product = (HO << 8) | LO; // new product is HO byte shifted into 16 bit position, w multiplier in LO position
PB = product & 1; // store previous end bit
phb = product & 0x8000; // check if highest bit is 0 or 1 before shifting to maintain
product >>= 1; // shift product to the right one
if (phb) product |= 0x8000; // force HO to 1 if originally was 1
CB = product & 1; // get current end bit
HO = product >> 8; // set new HO byte (the HO byte of the product)
LO = product & 0x00FF; // set new LO byte
}
return product;
}
// ---------------------------------------------------------------------------------------------------------------------
unsigned int ascii_to_integer(char *ascii_number, int size){
//------------------------------------------------------------------------------------------------------------------
unsigned int converted = 0x00000000;
for (int i = 0 ; i < size ; i ++ ) { // clear HO 11's then convert each number to its correct decimal position
converted = converted * 10 + ( *ascii_number ++ &= ~( 3 << 4 ) );
} // 0 + 1 = 1 * 10 = 10, 10 + 2 = 12, 12*10 = 120 + 3 = 123, etc.
return converted; // then set to 0 to clear those bits with &. the result is multiplied by current base 10 position
}
// ---------------------------------------------------------------------------------------------------------------------
void to_upper(char* d, int size){
// -----------------------------------------------------------------------------------------------------------------
for (int i = 0 ; i < size ; i ++) *d ++ &= ~ ( 1 << 5 );
// set 1, move it into position, flip it to zero, and the bit with that zero to clear
}
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
void to_lower(char* c, int size){
// -----------------------------------------------------------------------------------------------------------------
for (int i = 0 ; i < size ; i ++) *c ++ |= 1 << 5; // set 1 , move to position , or the 1 with the bit to set to 1
}
// ---------------------------------------------------------------------------------------------------------------------
unsigned short full_adder(uint8_t one, uint8_t two) {
// -----------------------------------------------------------------------------------------------------------------
// ~~ deep seek helped fix my original attempt which failed to carry correctly sometimes & did not have final carry
// -----------------------------------------------------------------------------------------------------------------
int shift = 0;
uint8_t carry = 0;
uint16_t sum = 0; // Store 8-bit sum + carry-out in bit 8
// -----------------------------------------------------------------------------------------------------------------
while (shift < 8) { // go through all 8 bits
uint8_t a_bit = (one >> shift) & 1; // start from LO bits
uint8_t b_bit = (two >> shift) & 1; // start from LO bits
uint8_t sum_bit = a_bit ^ b_bit ^ carry; // sum_bit is 1 when there's an odd number of 1s in the inputs
carry = (a_bit & b_bit) | (a_bit & carry) | (b_bit & carry); // carry-out exists if at least 2 of 3 inputs are 1
sum |= (sum_bit << shift ++ ); // set the current bit with the sum_bit then increment shift for next loop
}
return sum |= (carry << 8); // when done, store any carry-out in the 9th bit (bit 8)
}
// ---------------------------------------------------------------------------------------------------------------------
char *to_bits(unsigned int num){
// -----------------------------------------------------------------------------------------------------------------
char* bits
= malloc(sizeof(unsigned int) * sizeof(char));// 4 bytes for int and 1 byte for char = 4 bytes or 32 bits int shifts = 0; // how many shifts will be performed (32, 1 per bit)
// -----------------------------------------------------------------------------------------------------------------
while (shifts < 32) // start shifting
*bits ++ = ( num & 1 << shifts ++ ) ? '1' : '0'; // deref the char array, inc post, mask w/ << 1, pick outcome
// -----------------------------------------------------------------------------------------------------------------
return bits; // return the pointer (will need to be re-wound)
}
// ---------------------------------------------------------------------------------------------------------------------
// extra helpers
// ---------------------------------------------------------------------------------------------------------------------
void print_bits(char* ptr){
// -----------------------------------------------------------------------------------------------------------------
int cntr = 0; // while pointer isn't null, backtrack from current pointer address in memory, print char at mem add
while (*--ptr
) (cntr
== 4) ? cntr
= 0 , printf("_%c",*ptr
) : printf("%c",*ptr
) , cntr
++ ; }
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
void print_string(char* string, int size){
// -----------------------------------------------------------------------------------------------------------------
for (int i
= 0 ; i
< size
; i
++) (i
== 0) ? printf("\n%c", string
[i
]) : printf("%c", string
[i
]); }
// ---------------------------------------------------------------------------------------------------------------------