#include <8052.h>
#include <stdio.h>
//#include <string.h>
/* 
demonstrates how the incorrect check value of 0x29B1 may be reported 
for the test string "123456789" when it should be 0xE5CC. 
*/ 

#define  poly     	0x1021          /* crc-ccitt mask */ 
#define	 CR			0x0d
#define	 LF			0x0a

/* global variables */ 
unsigned char text[50]; 
unsigned int good_crc; 
unsigned int bad_crc; 
unsigned int text_length; 


void go(void); 
void repeat_character(unsigned char ch, unsigned int n);
void update_good_crc(unsigned int ch);
void update_bad_crc(unsigned int ch);
reflect(unsigned int ch);
//reflect();

//void update_bad_crc(unsigned char ch); 
void augment_message(); 

void main (void) 
{ 
	// Initialises serial port for 4800 baud at 12MHZ
	TH1 = 0xf3 ;
	TL1 = 0xf3 ;
	PCON |= 0x80 ;
	SCON = 0x50 ;
	TMOD = 0x20 ;
	TCON = 0x40 ;
 	TI 	 = 1;

	//
	printf("In main");
	
	
//    sprintf(text, "%s", ""); 
//    go(); 

//    sprintf(text, "%s", "A"); 
//    go(); 

    sprintf(text, "%s", "123456789"); 
    
    //text[0] = '1';
    //text[1] = '2';
    //text[3] = '3';
    //text[4] = '4';
    //text[5] = '5';
    //text[6] = '6';
    //text[7] = '7';
    //text[8] = '8';
    //text[9] = '9';
    //text[10] = '\0';
        
    go(); 

 //   repeat_character(65, 50); 
 //   go(); 

    while(1){} 
} 

  void go (void) 
//go (void)
{ 
    unsigned int ch,i;
    //unsigned int i; 

    good_crc = 0xffff; 
    bad_crc = 0xffff; 
    i = 0; 
    text_length= 0;
    
    while((ch=text[i])!=0) 
    { 
     _asm
      SETB P1.0
      CLR P1.1
     _endasm;
        ch = reflect(ch);///////what is wrong here?
               
        update_good_crc(ch); 
        update_bad_crc(ch); 
        i++; 
        text_length++; 
    } 
    augment_message(); 
    //bad_crc = bad_crc ^ 0xffff;
    printf("\nGood_CRC = %04X",good_crc); 
    printf(" Bad_CRC = %04X",bad_crc);  
   // good_crc = bad_crc ^ 0xffff
  //  printf("Bad_CRC = %04X",bad_crc); 
    printf(" Length = %u,  Text = %s",text_length,text); 
} 

void repeat_character (unsigned char ch, unsigned int n) 
{ 
    unsigned int i; 
    for (i=0; i<n; i++) 
    { 
        text[i] = ch; 
    } 
    text[n] = 0; 
} 

void update_good_crc (unsigned int ch)
{ 
    unsigned char i, v, xor_flag; 

    /* 
    Align test bit with leftmost bit of the message byte. 
    */ 
    v = 0x80; 

    for (i=0; i<8; i++) 
    { 
        if (good_crc & 0x8000) 
        { 
            xor_flag= 1; 
        } 
        else 
        { 
            xor_flag= 0; 
        } 
        good_crc = good_crc << 1; 

        if (ch & v) 
        { 
            /* 
            Append next bit of message to end of CRC if it is not zero. 
            The zero bit placed there by the shift above need not be 
            changed if the next bit of the message is zero. 
            */ 
            good_crc= good_crc + 1; 
        } 

        if (xor_flag) 
        { 
            good_crc = good_crc ^ poly; 
        } 

        /* 
        Align test bit with next bit of the message byte. 
        */ 
        v = v >> 1; 
    } 
} 

void augment_message (void) 
{ 
    unsigned char i, xor_flag; 

    for (i=0; i<16; i++) 
    { 
        if (good_crc & 0x8000) 
        { 
            xor_flag= 1; 
        } 
        else 
        { 
            xor_flag= 0; 
        } 
        good_crc = good_crc << 1; 

        if (xor_flag) 
        { 
            good_crc = good_crc ^ poly; 
        } 
    } 
} 

void update_bad_crc (unsigned int ch) 
{ 
    /* based on code found at 
    http://www.programmingparadise.com/utility/crc.html 
    */ 

    unsigned char i, xor_flag; 

    /* 
    Why are they shifting this byte left by 8 bits?? 
    How do the low bits of the poly ever see it? 
    */ 
    ch<<=8; 

    for(i=0; i<8; i++) 
    { 
        if ((bad_crc ^ ch) & 0x8000) 
        { 
            xor_flag = 1; 
        } 
        else 
        { 
            xor_flag = 0; 
        } 
        bad_crc = bad_crc << 1; 
        if (xor_flag) 
        { 
            bad_crc = bad_crc ^ poly; 
        } 
        ch = ch << 1; 
    } 
}

void putchar ( char ch)
{
	if (ch == LF)
	{
		while(!TI) {}
		TI = 0 ;
		SBUF = CR ;
	}
	while(!TI) {}
	TI = 0 ;
	SBUF = ch ;
}


 char getchar ()
{
	while(!RI) {}
	RI = 0 ;
	return(SBUF) ;
}
///////////////////////////////////////////////////////////////////////////////////// 
// subroutines
//unsigned long reflect (unsigned long crc, int bitnum)

reflect(unsigned int ch)
  {
// unsigned int reflect(unsigned int crc)
// reflect (unsigned int crc)
//  {
  //unsigned int ch;
//  unsigned int crc;
//unsigned char crc;
 //  char crc;
   int bitnum;

//reflects the lower 'bitnum of 'crc'
 // unsigned  i, j=1, crcout=0;
  unsigned i,j=1,chout=0;
  //unsigned crcout;
//ch = 'A';
bitnum = 8;

//printf("ch = %04x",ch);
 printf(" in reflect");
for (i=(unsigned int )1<<(bitnum-1);i;i>>=1) {//changed here
 //   if(crc & i) crcout|=j;
    if(ch & i) chout|=j;
    j<<=1;
    }
    
//    printf("crcout");
   // printf(" crc = %04X",crc); 
   // printf(" chout = %04X",chout);
    // ch = crcout;
   // printf(" Bad_CRC = %04X",bad_crc); 
    return (chout);
    }
