
#include <AT89X51.H>
#include <EQ5Firm.h>

#define TC			9	/* Timer correction */

code unsigned char	HalfStep[8] = { 0x99, 0xB1, 0xA5, 0xE4, 0x66, 0x72, 0x5A, 0xD8 };
code unsigned char	FullStep[9] = { 0x99, 0xA5, 0x66, 0x5A, 0x99, 0xA5, 0x66, 0x5A, 0xF0 };

unsigned int	ReloadRA, ReloadDEC;
unsigned char	TempP0, TempP2;

bit				FullStepRA, FullStepDEC;
bit				RaPosDir, DecPosDir;
unsigned char	StepRA, StepDEC;

unsigned char	RAPosition = 0, DECPosition = 0;

unsigned char	CurrentSpeed;

void DoSteps(void);

/*
 * Reload values for timers ;
 * Star speed
 */
unsigned int	ReloadRADefault = 0xC37B + TC;

/*
 * RA reload values for N - Visual ;
 * +2x, +8x, +16x, -2x, -8x, -16x ;
 * code unsigned int ReloadRA_V[6]={0xE1BD+TC, 0xF3E5+TC, 0xF947+TC, 0, 0xEBD4+TC, 0xF75B+TC};
 */
code unsigned int	ReloadRA_V[6] = { 0xE1BD + TC, 0xF3E5 + TC, 0xFA80 + TC, 0, 0xEBD4 + TC, 0xF947 + TC };

// +1x, +4x, +21x, -1x, -4x, -19x

/*
 * RA reload values for S - Astrophoto ;
 * +0.3x, +0.7x, +1x, -0.3x, -0.7x, -1x,
 */
code unsigned int	ReloadRA_P[6] = { 0xD172 + TC, 0xDC66 + TC, 0xE1BD + TC, 0xA98B + TC, 0x3644 + TC, 0 };

/*
 * DEC reload values for N - Visual ;
 * +2x, +8x, +16x, -2x, -8x, -16x
 */
code unsigned int	ReloadDEC_V[6] = { 0xC37B + TC, 0xF0DF + TC, 0xF9F3 + TC, 0xC37B + TC, 0xF0DF + TC, 0xF9F3 + TC };

/*
 * DEC reload values for S - Astrophoto ;
 * +0.3x, +0.7x, +1x, -0.3x, -0.7x, -1x,
 */
code unsigned int	ReloadDEC_P[6] = { 0x3644 + TC, 0xA98B + TC, 0xC37B + TC, 0x3644 + TC, 0xA98B + TC, 0xC37B + TC };


void main(void)
{
	ReloadRA = ReloadRADefault;
	ReloadDEC = ReloadRADefault;

	ReloadRA = 0;
	ReloadDEC = 0;

	ButtonDECPlus = 1;
	ButtonDECMinus = 1;
	ButtonRAPlus = 1;
	ButtonRAMinus = 1;

	P0 = 0x00;
	P2 = 0xFF;
	TempP0 = 0x00;
	TempP2 = 0xFF;

	InitTimers();
	ReloadRA = ReloadRADefault;

	while (1)		/* Main cycle. Check buttons do corrections */
	{
		DoSteps();

		/* Set Reload for timers. */
		CurrentSpeed = ToggleSpeed4x == 0 ? 1 : (ToggleSpeed2x == 0 ? 0 : 2);

		if (CurrentSpeed == 2 && Hemisphere == Visual)
			FullStepDEC = 1;
		else
			FullStepDEC = 0;
		if ((CurrentSpeed == 2 && Hemisphere == Visual) && (!ButtonRAMinus || !ButtonRAPlus))
			FullStepRA = 1;
		else
			FullStepRA = 0;
		//	if(ToggleSpeed4x==0)CurrentSpeed=1;
		//	if(ToggleSpeed2x==0)CurrentSpeed=0;
		//	if(ToggleSpeed4x==1 && ToggleSpeed2x==1)
		//		CurrentSpeed=2;
		if (ButtonRAPlus == 1 && ButtonRAMinus == 1)
		{
			ReloadRA = ReloadRADefault;
		}

		if (ButtonDECPlus == 1 && ButtonDECMinus == 1)
		{
			ET1 = 0;
			StopDEC();
		}

		/* North - Visual */
		if (Hemisphere == Visual)
		{
			/* Set delays for visual mode */
			if (ButtonRAMinus == 0)
			{
				ReloadRA = ReloadRA_V[CurrentSpeed];
			}

			if (ButtonRAPlus == 0)
			{
				ReloadRA = ReloadRA_V[3 + CurrentSpeed];
			}

			if (ButtonDECMinus == 0)
			{
				ReloadDEC = ReloadDEC_V[CurrentSpeed];
				ET1 = 1;
			}

			if (ButtonDECPlus == 0)
			{
				ReloadDEC = ReloadDEC_V[3 + CurrentSpeed];
				ET1 = 1;
			}
		}
		else		/* South - Astrophoto. No reverse for RA. Only make it slower. */
		{
			/* Set delays for astrophoto mode */
			if (ButtonRAMinus == 0)
			{
				ReloadRA = ReloadRA_P[CurrentSpeed];
			}

			if (ButtonRAPlus == 0)
			{
				ReloadRA = ReloadRA_P[3 + CurrentSpeed];
			}

			if (ButtonDECMinus == 0)
			{
				ReloadDEC = ReloadDEC_P[CurrentSpeed];
				ET1 = 1;
			}

			if (ButtonDECPlus == 0)
			{
				ReloadDEC = ReloadDEC_P[3 + CurrentSpeed];
				ET1 = 1;
			}
		}

		if (ButtonDECPlus == 0)
			DecPosDir = Decrease;
		if (ButtonDECMinus == 0)
			DecPosDir = Increase;

		RaPosDir = Decrease;

		if (ButtonRAMinus == 0 || Hemisphere == Astrophoto)
			RaPosDir = Decrease;
		if (ButtonRAPlus == 0 && Hemisphere == Visual)
			RaPosDir = Increase;

		if (ButtonRAPlus == 0 || ButtonRAMinus == 0)
			LedRed = 1;
		else
			LedRed = 0;

		if (ButtonDECPlus == 0 || ButtonDECMinus == 0)
			LedGreen = 1;
		else
			LedGreen = 0;
	}
}

void StopDEC(void)
{
	P0 = (P0 & 0xF0) | (FullStep[8] & 0x0F);
	P2 = (P2 & 0x0F) | (FullStep[8] & 0xF0);
}

void DoSteps(void)
{
	unsigned char	RAPhase, DECPhase;

	if (StepDEC != 0 && ReloadDEC != 0)
	{
		StepDEC = 0;
		DECPhase = FullStepDEC == 1 ? FullStep[DECPosition] : HalfStep[DECPosition];

		/*
		 * DECPhase=FullStep[DECPosition];
		 */
		TempP0 = TempP0 & (0xF0 | DECPhase);
		TempP2 = TempP2 | (0xF0 & DECPhase);
		P0 = TempP0;
		P2 = TempP2;
		TempP0 = (TempP0 & 0xF0) | (DECPhase & 0x0F);
		TempP2 = (TempP2 & 0x0F) | (DECPhase & 0xF0);
		P0 = TempP0;
		P2 = TempP2;

		if (DecPosDir)
			DECPosition = ++DECPosition & 7;
		else
			DECPosition = --DECPosition & 7;
	}

	if (StepRA != 0 & ReloadRA != 0)
	{
		StepRA = 0;
		RAPhase = FullStepRA == 1 ? FullStep[RAPosition] : HalfStep[RAPosition];

		// RAPhase=HalfStep[RAPosition];

		RAPhase = (RAPhase << 4) | (RAPhase >> 4);
		TempP0 = TempP0 & (0x0F | RAPhase);
		TempP2 = TempP2 | (0x0F & RAPhase);
		P0 = TempP0;
		P2 = TempP2;
		TempP0 = (TempP0 & 0x0F) | (RAPhase & 0xF0);
		TempP2 = (TempP2 & 0xF0) | (RAPhase & 0x0F);
		P0 = TempP0;
		P2 = TempP2;
		if (RaPosDir)
			RAPosition = ++RAPosition & 7;
		else
			RAPosition = --RAPosition & 7;
	}
}

void InitTimers(void)
{
	TR0 = 0;
	TMOD |= 0x01;
	TL0 = 0x77;
	TH0 = 0x77;
	ET0 = 1;
	TR0 = 1;

	TR1 = 0;
	TMOD |= 0x10;
	TL1 = 0xAA;
	TH1 = 0xAA;
	ET1 = 1;
	TR1 = 1;
	EA = 1;
}

timer0_int()
interrupt TF0_VECTOR using 1
{
	unsigned int	Reload;

	Reload = ReloadRA;

	Reload += TL0;
	TL0 = Reload & 0xFF;
	TH0 += Reload >> 8;
	ET0 = 1;
	EA = 1;
	TR0 = 1;
	StepRA = 1;
}

timer1_int()
interrupt TF1_VECTOR using 2
{
	unsigned int	Reload;

	Reload = ReloadDEC;

	Reload += TL1;
	TL1 = Reload & 0xFF;
	TH1 += Reload >> 8;
	ET1 = 1;
	EA = 1;
	TR1 = 1;
	StepDEC = 1;
}