#include <reg52.h>

#include "Page0.h"
#include "PalmChip.h"

#include "p_dsp.h"

#ifdef VER_IPH_E00
#define	MAX_VOL				31
#define	MIN_VOL				0

extern CCHAR _cTestStr[];
extern CCHAR _cTestMenuStr[];
#endif

extern volatile BOOLEAN Timer_bIndicated;		// indicate 0.02 second timer
extern volatile BOOLEAN Serial_bRun;			// Serial data exchange need to run seperately

void main(void)
{
	DCHAR iVal;

	// Reset Palm1
	XBYTE[SYS_RESET1] = 0xf7;
	XBYTE[SYS_RESET1] = 0x0;
	XBYTE[SYS_RESET2] = 0xef;
	XBYTE[SYS_RESET2] = 0x0;

	Led_On(NORMAL_LIGHT);
	Led_On(KEYPAD_LIGHT);

#ifdef MT28F016
	XBYTE[IO_HI_ENABLE] |= 0x20;
#ifdef VER_WG3051
	XBYTE[IO_HI_DOUT] |= 0xdf;	// PIO13 = 0
#else
	XBYTE[IO_HI_DOUT] |= 0x20;	// PIO13 = 1
//	XBYTE[IO_HI_DOUT] &= 0xdf;	// PIO13 = 0
#endif
#endif

	XBYTE[IO_LO_ENABLE] |= AC97_PIO_RESET_OR;
	XBYTE[IO_LO_DOUT] |= AC97_PIO_RESET_OR;
	XBYTE[IO_LO_DOUT] &= AC97_PIO_RESET_AND;
	SysSleep(5000);
	XBYTE[IO_LO_DOUT] |= AC97_PIO_RESET_OR;

	XBYTE[IO_LO_ENABLE] |= NE2000_PIO_RESET_OR;
	XBYTE[IO_LO_DOUT] &= NE2000_PIO_RESET_AND;
	XBYTE[IO_LO_DOUT] |= NE2000_PIO_RESET_OR;
	SysSleep(5000);
	XBYTE[IO_LO_DOUT] &= NE2000_PIO_RESET_AND;

//	Led_Blink(WATCHDOG_TIME);
	PLLInitialize();
	Led_Off(KEYPAD_LIGHT);

	DisplayInitialize();
//	DisplayClearScreen();
	DisplayCursor(FALSE);
	DisplayString(g_cBooting, 0);

#ifdef VER_IPH_E00
	XBYTE[IO_LO_ENABLE] |= 0x40;		// IOPAD4
	XBYTE[IO_LO_DOUT] |= 0x40;
#ifdef E00_NEW_HW
	XBYTE[IO_HI_ENABLE] |= 0x10;		// IOPAD5
	XBYTE[IO_HI_DOUT] |= 0x10;
	L3DataOn();							// IOPAD7
	L3ModeOn();
#else
	XBYTE[IO_HI_ENABLE] |= 0x20;		// IOPAD5
	XBYTE[IO_HI_DOUT] |= 0x20;
#endif // E00_NEW_HW
#endif

	// Ethernet interrupt connected PIO 9
    XBYTE[IO_HI_INTEN] |= NE2000_PIO_INT_OR;
	XBYTE[INT_ENABLE] |= INT_MASK_IO;	// 0x04

	BootIndication(0);

	// we have to wait 2 seconds during the whole NE2000 init, so we do it step by step to avoid silly wait
	Ne2000Initialize_Step1();
	SdramInitialize();
	DspInitialize();
	Ac97Initialize();
	iVal = KeypadInitialize();
	BootIndication(1);
	if (iVal == KEYPAD_STAR)
	{
		SdramStartup();			// load settings which was load to sdram in page3 code
	}
	else if (iVal == KEYPAD_WELL)
	{	// into settings
#ifdef SETTINGS_PAGE
		SwitchPage(SETTINGS_PAGE);
#else
		SdramStartup();			// same effect as pressing KEYPAD_STAR -> stay at Page0
#endif
	}
	else
	{	// '*' or '#' is not pressed, we will load settings first
#ifdef OPTIONS_PAGE
		SwitchPage(OPTIONS_PAGE);
#elif defined SETTINGS_PAGE
		SwitchPage(SETTINGS_PAGE);
#endif
	}
	Led_On(SECOND_LIGHT);
	SysSleep1Second();												// Pause
	Ne2000Initialize_Step2();
	SysSleep1Second();												// Pause
	KeypadStartup();
//	DspStartup();
#ifdef _USE_FAKE_FXO
	SwitchToFXO(FALSE);
#endif
	ControlInitialize();
	Ac97Startup();
	if (Ne2000Initialize())
	{
		TcpipInitialize();
#ifdef VER_IPH_E00            //Diagnostic test		
#ifndef VER_IPH_E00_2G
		DisplayString((PCCHAR)"      i P H - E 0 0     ", 0);     
		DisplayString((PCCHAR)"Hardware Diagnostic Test", 1);
#else
		DisplayString((PCCHAR)"   iPhone-E00   ", 0);     
		DisplayString((PCCHAR)" H/W Diagnostic ", 1);
#endif
		SysSleep1Second();
		SysSleep1Second();
		// Set Handset/Handfree in/outs
		Ac97_iHandsetOutputVol = MAX_VOL-10;
		Ac97_iHandfreeOutputVol = MAX_VOL;
		Ac97_iHandsetInputVol = MIN_VOL;
		Ac97_iHandfreeInputVol = MIN_VOL;
		Ac97SetOutputVol();
		Ac97SetInputVol();
		// Display Start Menu
		DisplayString((PCCHAR)_cTestStr, 0);
		DisplayString((PCCHAR)_cTestMenuStr, 1);
#else
		DisplayString((PCCHAR)"Page0 running", 0);
#endif
	}
	else
	{
		XBYTE[IO_HI_INTCLR] = 0xff;	// Clear io edge irq
		DisplayString(g_cNetwork, 0);
		DisplayString(g_cFailed, 1);
	}
	iVal = 0;
    while (1)
    {
		Ac97Run();
		KeypadRun();
		Ne2000Run();
		UdpDebugUpdate();
		if (Timer_bIndicated)
		{
			iVal ++;
			if (PIO_iHookFlashTimer)
			{
				PIO_iHookFlashTimer ++;
				if (PIO_iHookFlashTimer > 20)
				{
					// it is hook down event.
					PIO_iHookFlashTimer = 0;
					PIO_bHandsetUp = FALSE;
					OnHandset();
				}
			}
			if (iVal == 50)
			{
				TcpipHandleTimer();
#ifndef VER_IPH_E00
				Led_Blink(NORMAL_LIGHT); // LED_MSGLINE_GREEN
#endif
				iVal = 0;
			}
			Timer_bIndicated = FALSE;
		}
	}
}

void PalmInterrupt() interrupt 2	//	using 2
{
	DCHAR iDPS, iIntVal;
	DCHAR iDPH, iDPL;

	iDPH = DPH1;
	iDPL = DPL1;
	iDPS = DPS;	// Push DPS value
	DPS = 0;

    iIntVal = XBYTE[INT_VALUE];

    if (iIntVal & INT_MASK_IO)
	{
		IoKeyHandleInterrupt();
    }
	if (iIntVal & INT_MASK_KEY)
	{
		KeypadHandleInterrupt();
	}
	if (iIntVal & INT_MASK_DMA)
	{
		Ac97HandleInterrupt();
	}
	if (iIntVal & INT_MASK_DSP)
	{
		XBYTE[INT_CLR] |= INT_MASK_DSP;
		DspHandleInterrupt();
	}

	DPH1 = iDPH;
	DPL1 = iDPL;
	DPS = iDPS;	// Pop DPS value
}
