/*
================================ COPYRIGHT ================================
The contents of this file are subject to the VTech Informations Ltd. License
of VT-OS Ver. 1.1 operating system (the "License"); you may not use this 
file except in compliance with the License.  

Software distributed under the License is distributed on an "AS IS" basis, 
WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License 
for the specific language governing rights and limitations under the License.
  
The Original Code is VT-OS Ver. 1.1 Operating System, released 
on October 1st, 1999
	
The Initial Developer of the Original Code is VTech Informations Ltd.  All 
codes are Copyright (C) VTech Informations Ltd. 1999.  All Rights Reserved.
===========================================================================
*/

/*
===========================================================================
File        :   sioloop1.c
Author(s)   :   Garick Ngai
Company     :   VTech Informations Ltd.
Project     :   Helio 
Date:	    :   October 1st, 1999
Purpose:	:   SIO
Revision    :   1.1
Note        :   None
===========================================================================
*/              

//Version 1.1 --  The SIO data input pin become output status when without use

#include "tmrapi.h"
#include "sio.h"
#include "sio_rxtx.h"
#include "Mmu.h"
#include "qtype.h"
#include "eventmgr.h"
#include "msg.h"
#include "kernel.h"
#include "intc.h"
#include "dev_pwr.h"
#include "system.h"
#include "lcdapi.h"
#include "autopwr.h"
#include "hookmgr.h"
#include "resmgr.h"
#include "DataType.h"
#include "CpuIoReg.h"
#include "el.h"
#include "autopwr.h"

extern BitmapTemplate   sio_popup_current_display_image;

AppID sio_appid;

volatile WORD    sio_rdstate;

volatile UWORD   count_rx_error;        /* Count no. of time the rx. first byte error*/

volatile UWORD   acc_data_size;         /* Get the no. of Acc. Data Bytes */
volatile UWORD   check_get4b_data;      /* Get the 4Bytes to check the Acc. Data Size */
volatile UWORD   en_download_timer;
volatile UWORD   get_no_rx_data;        /* check Get no. of rx. Acc.data */

volatile UWORD   en_acc_data_timer;
volatile UWORD   download_speed;
volatile UWORD   program_id;
volatile UWORD   cut_power;
volatile UWORD   Last_prog_dl;
volatile UWORD   rot_90_degree;
volatile UWORD   check_prog4b_size;     /* Get the 4Bytes to check the Acc. Data Size */
volatile UWORD   get_rx_bprog_data;     /* check Get no. of rx. Download Program data */
volatile UWORD   checksum_program_B;
volatile UWORD   program_size;          ////////**** Get the no. of Program Size Block---Block (Block x 20 = data)*****///////
volatile UWORD   count_get_prog_block;  /* Count have rx. no. of Program Block---Block (Block x 20 = data)*****///////
//////////////////////////////////////////////////////////////////////
////////////////Install_complete_flag  ///////////////////////////////
////////////////if = 0  then no prog. need DL ////////////////////////
////////////////if = 1  then want DL prog.    ////////////////////////
////////////////if = 2  then prog. DL Complete////////////////////////
//////////////////////////////////////////////////////////////////////
volatile UWORD   Install_complete_flag; 
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

volatile UWORD   tx_interrupt_rdy;
volatile UWORD   tx_command_data;

volatile UWORD   test_rdy;
volatile UWORD   accessory_plug_in;
volatile UWORD   sio_download_driver;

UBYTE buff0[35],buff1[35],hookbuff[8],syscall_buff[8];
volatile BOOLEAN rx_byte;                  /* rx = 0 ,  tx = 1 */
volatile BOOLEAN download_timer_active;    /* in-active = 0, active = 1 */
volatile BOOLEAN acc_data_timer_active;    /* in-active = 0, active = 1 */



//////////// For MMU Store Program ///////////
UBYTE *ptr;
UBYTE buffer;
UBYTE *sio_buffer_ptr;
UWORD *pgtbl;
USHORT appid;
BYTE drv_name[19];

//////////// For Hook Interrupt Get Information ///////////
volatile UBYTE *hookinfo;
volatile UWORD num_hookint;
volatile UWORD count_hookint;
volatile UWORD each_hookdata;

//////////// For System Call Function Information ///////////
volatile UBYTE *syscall_info; 
volatile UWORD num_syscall;
volatile UWORD count_syscall;
volatile UWORD each_syscall_data;

volatile UWORD en_sio_dev_pin_check;
volatile UWORD rd_sio_dev_pin;
volatile UWORD dis_sio_dev_pin_check;
volatile UWORD rd_sio_dev_moveout;


///////////// For Program Install /////////////////////////
UBYTE attr1;
UBYTE attr2;
UWORD prog_code_size;
UWORD res_offset;
UBYTE icon_data[448];
UBYTE buff_icon_data[33];
UWORD check_num_icon_data;
UWORD first_sys_call;
UBYTE hook_flag;
UWORD load_sio_app;
UWORD load_sio_app_not_first;
UBYTE count_first_rdy = 0;

volatile UWORD count_icon_block;
volatile UWORD num_icon_block_get;

InstallAppInf *handle;
USHORT reg_index;

void ProgTimeOut()
{
#ifdef DEBUG
    printf("\nDownLoad Program TimeOut");
#endif
}

void AccDataTimeOut()
{
#ifdef DEBUG
    printf("\nGet Accessory Data TimeOut");
#endif
}

void SIOInit()
{    
    SwSIOInit();
}

void SwSIOInit()
{
	
	register WORD *CpuReg;
	CpuReg = CPU_IOREG_BASE;    /* defined in CpuIoReg.h */
	
#ifdef DEBUG1
	printf("\nSIO init");
#endif
	
	sio_download_driver = 0;
	sio_rdstate = 0;
	count_rx_error = 0;
	rx_byte     = 0;
	
	en_acc_data_timer = 0;
	check_get4b_data = 0;
	acc_data_size = 0;
	
	en_download_timer = 0;
	check_prog4b_size = 0;
	download_speed = 0;
	program_id = 0;
	cut_power = 0;
	Last_prog_dl = 0;
	rot_90_degree = 0;
	program_size = 0;
	get_rx_bprog_data = 0;
	checksum_program_B = 0;
	count_get_prog_block = 0;
	Install_complete_flag = 0;
	tx_interrupt_rdy = 0;
	
	num_hookint = 0;
	count_hookint = 0;
	each_hookdata = 0;
	hookinfo = hookbuff;
	
	num_syscall = 0;
	count_syscall = 0;
	each_syscall_data = 0;
	syscall_info = syscall_buff;
	
	sio_appid = 0;
	test_rdy = 0;
	accessory_plug_in = 0;
	
	attr1=0;
	attr2=0;
	prog_code_size=0;
	res_offset=0;
	check_num_icon_data = 0;
	count_icon_block = 0;
	num_icon_block_get = 0;
	first_sys_call = 0;
	hook_flag = 0;
	load_sio_app = 0;
	load_sio_app_not_first = 0;
	count_first_rdy = 0;
	
	CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
	CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
	CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
	
	CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_DATA_IN_NO_USE;
	CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
	CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
	CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
	
	CpuReg[IOREG_MFIO_POWER_DOWN] |= SIO_CAN_POWER_DOWN_PIN;
	CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DEVDET|SIO_RDY);
	//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY);
	
	//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY|SIO_DEVDET_POWER_EN|SIO_DATA_IN_NO_USE);
	
	
	DIS_MFIOPOSINT(30);
	CPU->REG_INT_STATUS_3 = MFIOPOSINT(30); // POSONBUTNINT
	
	CPU->REG_INT_STATUS_4 = MFIONEGINT(30); // POSONBUTNINT
	ENA_MFIONEGINT(30);
	
	DIS_MFIONEGINT(28);
	//        CPU->REG_INT_STATUS_4 = MFIONEGINT(28);
}



void SIODebounCheck()
{
    UWORD nop,siodevdelay;
    register WORD *CpuReg;
    CpuReg = CPU_IOREG_BASE;    /* defined in CpuIoReg.h */
	
    DIS_MFIONEGINT(30);
	
	///// when SIO in use, set the data in pin at input
	//    CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DATA_IN_NO_USE);
    CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
	
	
    if(NormalOperation == FALSE)
    {
        SemiPowerOff = TRUE;
    }
    en_sio_dev_pin_check = 0;
    en_sio_dev_pin_check = TmrIntEnableIntPen(10, SioDevDet);
	
}

void SioDevDet()
{
    register WORD *CpuReg;
    CpuReg = CPU_IOREG_BASE;    /* defined in CpuIoReg.h */
	
    if(en_sio_dev_pin_check != 0)
    {
        TmrIntDisableInt(en_sio_dev_pin_check);
        en_sio_dev_pin_check = 0;
    }
	
	
    rd_sio_dev_pin = 0;
    rd_sio_dev_pin = CPU->REG_MFIO_DATA_IN;
    rd_sio_dev_pin &= 0x40000000;
	
    if(rd_sio_dev_pin  == 0)
    {
        if(NormalOperation == FALSE)
        {
            //// when SIO in use, set the data in pin at input
			//            CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DATA_IN_NO_USE);
            CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
			
            SemiPowerOff = FALSE;
            WakeCpuUp = TRUE;
            en_sio_dev_pin_check = TmrIntEnableIntPen(10, ActiveSIORdy);
        }
        else
        {
            en_sio_dev_pin_check = TmrIntEnableIntPen(10, ActiveSIORdy);
        }
        CPU->REG_INT_STATUS_3 = MFIOPOSINT(30); // POSONBUTNINT
        ENA_MFIOPOSINT(30);
    }
    else
    {
        if(NormalOperation == FALSE)
        {
            SemiPowerOff = FALSE;
            WakeCpuUp = FALSE;
        }
        SwSIOInit();
    }
}

void ActiveSIORdy()
{
    register WORD *CpuReg;
    CpuReg = CPU_IOREG_BASE;    /* defined in CpuIoReg.h */
	
    if(en_sio_dev_pin_check != 0)
    {
        TmrIntDisableInt(en_sio_dev_pin_check);
        en_sio_dev_pin_check = 0;
    }
	
    CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
    CPU->REG_INT_STATUS_4 = MFIONEGINT(28);
    ENA_MFIONEGINT(28);
}

void DisSioDevDet()
{
	DIS_MFIOPOSINT(30);
	if(NormalOperation == FALSE)
	{
		SemiPowerOff = TRUE;
	}
	dis_sio_dev_pin_check = 0;
	dis_sio_dev_pin_check = TmrIntEnableIntPen(30, SioDevMoveOut);
}


void SioDevMoveOut()
{
	
    if(dis_sio_dev_pin_check != 0)
    {
        TmrIntDisableInt(dis_sio_dev_pin_check);
        dis_sio_dev_pin_check = 0;
    }
    rd_sio_dev_moveout = 0;
    rd_sio_dev_moveout = CPU->REG_MFIO_DATA_IN;
    rd_sio_dev_moveout &= 0x40000000;
	
    if(rd_sio_dev_moveout != 0)
    {
		
		//////////////////////////////////////////////////////////////////////
		/////////////////check if the prog. DL not complete///////////////////
		//////////////////////////////////////////////////////////////////////
		
		if(Install_complete_flag == 1) ///DL prog. in processing///
		{
			SysRemoveApp(appid);
			Install_complete_flag = 0;
#ifdef DEBUG
			printf("\nSysRemove");
#endif
		}
		//////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////
		
		
		//////////////////////////////////////////////////////////////////////
		//////////////////// Close the sio app.//////////////////////////////
		//////////////////////////////////////////////////////////////////////
		if(sio_appid != 0)
		{
			SIOPopupRestoreRunningApp();
		}
		//////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////
		//////////////////////////////////////////////////////////////////////
		LcdSetOrientation(0);
		SwSIOInit();
		if(NormalOperation == FALSE)
		{
			SemiPowerOff = FALSE;
			WakeCpuUp = FALSE;
		}
    }
    else
    {
        CPU->REG_INT_STATUS_3 = MFIOPOSINT(30); // POSONBUTNINT
        ENA_MFIOPOSINT(30);
        if(NormalOperation == FALSE)
        {
			SemiPowerOff = FALSE;
			WakeCpuUp = FALSE;
        }
    }
}

UWORD icon_slot, install_inf_slot;
UWORD sio_byte_rec = 0;
UWORD GetIconSlot()
{
	UWORD i;
	InstallAppInf *handle;
	UBYTE icon_slot_c[APP_MAX - TOTAL_PRE_INSTALL_APP];
	
	for(i=0;i<APP_MAX - TOTAL_PRE_INSTALL_APP;i++)
		icon_slot_c[i] = 1;
	
	SysGetInstallAppHandle(&handle);
	
	for(i=0;i<APP_MAX - TOTAL_PRE_INSTALL_APP;i++)
	{
		if(handle[i].icon_index < APP_MAX - TOTAL_PRE_INSTALL_APP)
			icon_slot_c[handle[i].icon_index] = 0;
	}
	
	for(i=0;i<APP_MAX - TOTAL_PRE_INSTALL_APP;i++)
		if(icon_slot_c[i])  break;
		
        if(i >= APP_MAX - TOTAL_PRE_INSTALL_APP)
			/* cannot hold any more prog */
			return 0xff;
		
        icon_slot = i;
        return i;      
}

UWORD GetInstallInfEntry()
{
	WORD i;
	InstallAppInf *handle;
	
	SysGetInstallAppHandle(&handle);
	
	install_inf_slot = 0xff;
	
	for(i=0;i<APP_MAX - TOTAL_PRE_INSTALL_APP;i++)
		if(handle[i].reg_entry_index == 0xff)
		{
			install_inf_slot = i;
			break;
		}
		
        return install_inf_slot;      
}

#define APP_ICON_SIZE (APP_ICON_WIDTH * APP_ICON_HEIGHT * APP_ICON_BIT_PER_PIXEL / 8)
UBYTE *ResGetInstallIconData();
void SIORdy()
{
	
	
    UWORD rx_data,nop,j;
    volatile UWORD i, checksum, output_bit;
    UWORD syscall_num;
    UWORD syscall_addr;
    UWORD int_num;
    UWORD int_addr;
    UBYTE *idata;
	
	
    if(NormalOperation == FALSE)
    {
        SemiPowerOff = TRUE;
    }
	
    if(rx_byte == 0)
    {
        if( download_timer_active = 1 )
        {
            download_timer_active = 0;
        }
		
        if( acc_data_timer_active = 1 )
        {
            acc_data_timer_active = 0;
        }
		
		
		
        SIORecieve(&rx_data);
		/*
        rx_data = 0x00;
        i=0;
		
		  do
		  {
          CPU->REG_MFIO_DATA_OUT &= 0xFFFF7FFF;
          rx_data |= ( ((CPU->REG_MFIO_DATA_IN  >> 13) & 0x00000001) << i);
          CPU->REG_MFIO_DATA_OUT |= 0x00008000; // set clk high //
          i++;
		  }while( i < 8 );
		  
		*/
		
#ifdef DEBUG1
		if(test_rdy < 8)
		{
			printf("\nfirst 8 rx_data = %x",rx_data);
			test_rdy++;
		}
#endif
		
        switch (sio_rdstate)
        {
			
		case  7  : /* Get the Hook interrupt Information */
			
			*hookinfo++ = rx_data;
			each_hookdata++;
			
#ifdef DEBUG
			//               printf("\n each_hookdata = %x", each_hookdata);
#endif
			if(each_hookdata == 8)
			{
				
#ifdef DEBUG
				printf("\ncount_hookint = %x",count_hookint);
				printf("\nnum_hookint = %x", num_hookint);
#endif
				
				int_num = 0;
				int_addr = 0;
				each_hookdata = 0;
				hookinfo -= 8;
				
#ifdef DEBUG
				if( count_hookint < num_hookint )
				{
					printf("\n hookinfo = ");
					for(i=0;i<8;i++)
					{
						printf("%x", *(((UBYTE *)hookinfo)+i));
					}
				}
#endif
				int_num |= (*(((UBYTE *)hookinfo)+0)) << 24;
				int_num |= (*(((UBYTE *)hookinfo)+1)) << 16;
				int_num |= (*(((UBYTE *)hookinfo)+2)) << 8;
				int_num |= (*(((UBYTE *)hookinfo)+3)) << 0;
				int_addr |= (*(((UBYTE *)hookinfo)+4)) << 24;
				int_addr |= (*(((UBYTE *)hookinfo)+5)) << 16;
				int_addr |= (*(((UBYTE *)hookinfo)+6)) <<  8;
				int_addr |= (*(((UBYTE *)hookinfo)+7)) <<  0;
				
				if(int_num == 0xfffffffe)
				{
#ifdef DEBUG
					printf("\n int addr(hex) = %08x ", int_addr);
					printf("\n int addr(UBYTE) = %d ", (UBYTE) int_addr);
#endif
					IntSetHookAddr((UBYTE) int_addr, pgtbl, appid);
					count_hookint++;
				}
				else
				{
					if(int_num == 0xffffffff)
					{
#ifdef DEBUG
						printf("\nhook_flag");
#endif
						hook_flag = 1;
					}
					else
					{
						count_hookint++;
						
						if(hook_flag == 1)
						{
#ifdef DEBUG
							printf("\nint_num = %x",int_num);
							printf("\nint_addr = %x",int_addr);
#endif
							IntSetActive(IntHookISR(appid, int_num, int_addr));
						}
						else
						{
#ifdef DEBUG
							printf("\nsys_num = %x",int_num);
							printf("\nsys_addr = %x",int_addr);
#endif
							SysHookSyscall(appid, int_num, (UWORD*)int_addr);
							if(!first_sys_call)
								first_sys_call = int_num;
						}                                                                
					}
				}
				if( count_hookint == num_hookint )
				{
					num_hookint = 0;
					count_hookint = 0;
					each_hookdata = 0;
					hookinfo = hookbuff;
					sio_rdstate = 0 ;
					Install_complete_flag = 0;
					/*
					if(first_sys_call)
					DIS_GBL_INT
					//                              SysCall(first_sys_call);
					ENA_GBL_INT
					*/
					rx_byte = 1;
					tx_interrupt_rdy = 1;
					tx_command_data = CHECKSUM_OK; // Confirm 20B Block Rx. OK //
					CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
#ifdef DEBUG_LOAD_APP
					printf("\n count_hookint == num_hook && intInstall_complete_flag = %d",Install_complete_flag);
#endif
					/*
					if((sio_rdstate == 0) && (Last_prog_dl == 1))
					{
					sio_appid = 0;
					}
					*/
					if((attr1 & 0x10) == 0x10)
					{
						SysGetInstallAppHandle(&handle);
						SysGetAppEntryIndex(appid, &reg_index);
						handle[install_inf_slot].reg_entry_index = reg_index;
						handle[install_inf_slot].icon_index = icon_slot;
					}
					
				}
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                        if(sio_rdstate == 0)
#ifdef DEBUG
				printf("\nsio_rdstate = %d, Last_prog_dl = %d",sio_rdstate,Last_prog_dl);
#endif
				if((sio_rdstate == 0) && (Last_prog_dl == 1))
				{
					SIOPopupRestoreRunningApp();
					sio_appid = 0;
				}
				//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				
                       }
                       break;
					   //////////////////////////////////////////////////////////////////////////////
					   /////////////////Need to Correct /////////////////////////////////////////////
					   //////////////////////////////////////////////////////////////////////////////
            case  6  : /* Get No. of the Hook interrupt */
				num_hookint = rx_data;
				hook_flag = 0;
				first_sys_call = 0;
				
#ifdef DEBUG
				printf("\ncase 6 num_hookint = %x", num_hookint);
#endif
				
				if(num_hookint == 0)
				{
					num_hookint = 0;
					count_hookint = 0;
					each_hookdata = 0;
					hookinfo = hookbuff;
					sio_rdstate = 0 ;
					Install_complete_flag = 0;
					/*
					if(first_sys_call)
					DIS_GBL_INT
					//                              SysCall(first_sys_call);
					ENA_GBL_INT
					*/
					rx_byte = 1;
					tx_interrupt_rdy = 1;
					tx_command_data = CHECKSUM_OK; // Confirm 20B Block Rx. OK //
					CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
#ifdef DEBUG_LOAD_APP
					printf("\n count_hookint == 0 && intInstall_complete_flag = %d",Install_complete_flag);
#endif
					
#ifdef DEBUG
					printf("\nsio_rdstate = %d, Last_prog_dl = %d",sio_rdstate,Last_prog_dl);
#endif
					if((sio_rdstate == 0) && (Last_prog_dl == 1))
					{
						SIOPopupRestoreRunningApp();
						sio_appid = 0;
					}
					
					if((attr1 & 0x10) == 0x10)
					{
						SysGetInstallAppHandle(&handle);
						SysGetAppEntryIndex(appid, &reg_index);
						handle[install_inf_slot].reg_entry_index = reg_index;
						handle[install_inf_slot].icon_index = icon_slot;
					}
				}
				else
				{
					sio_rdstate++ ;
				}
				
				break;
				//////////////////////////////////////////////////////////////////////////////
				//////////////////////////////////////////////////////////////////////////////
				//////////////////////////////////////////////////////////////////////////////
            case  5  :
#ifdef DEBUG
				//printf("\nicon_rx_data = %x", rx_data);
#endif
				buff_icon_data[count_icon_block++] = rx_data;
				
				if(count_icon_block == SIO_BLOCK_SIZE)
				{
#ifdef DEBUG
					//printf("\n count_icon_block = %d", count_icon_block);
					//printf("\n num_icon_block_get = %d", num_icon_block_get);
#endif
					checksum_program_B = 0;
					for(i=0; i<SIO_BLOCK_SIZE; i++)
					{
						checksum_program_B += buff_icon_data[i];
						checksum_program_B &= 0xFF;
					}
					
#ifdef DEBUG
					//printf("\n checksum_icon_B  = %x", checksum_program_B);
#endif
					
					if( (checksum_program_B & 0x000000FF) == 0 )
					{
						for(i=0; i<SIO_BLOCK_SIZE-1; i++)
						{
							icon_data[i+(num_icon_block_get * 32)] = buff_icon_data[i];
#ifdef DEBUG
							//printf("\n buff_icon_data[i] = %x", buff_icon_data[i]);
							//printf("\n icon_data = %x", icon_data[i+(num_icon_block_get * 32)]);
							//printf("\nbuff_icon_data[%d] = %x",i,buff_icon_data[i]);
							//printf("\nicon_data[%d] = %x",i+(num_icon_block_get * 32),icon_data[i+(num_icon_block_get * 32)]);
#endif
						}
						count_icon_block = 0;
						num_icon_block_get++;
						
						if(num_icon_block_get >= 13)
						{
							
#ifdef DEBUG
						/*
						printf("\n icon_data[0] = %x", icon_data[0]);
						printf("\n icon_data[1] = %x", icon_data[1]);
						printf("\n icon_data[2] = %x", icon_data[2]);
						printf("\n icon_data[3] = %x", icon_data[1]);
						printf("\n icon_data[4] = %x", icon_data[2]);
						printf("\n icon_data[5] = %x", icon_data[1]);
						printf("\n icon_data[6] = %x", icon_data[2]);
						printf("\n icon_data[404] = %x", icon_data[406]);
						printf("\n icon_data[405] = %x", icon_data[406]);
						printf("\n icon_data[406] = %x", icon_data[406]);
						printf("\n icon_data[407] = %x", icon_data[407]);
							*/
#endif
							
							check_num_icon_data = 0;
							GetInstallInfEntry();
							GetIconSlot();
							idata = ResGetInstallIconData();
							idata += 56;
							idata += icon_slot * 472;  /* position to icon data start */
							for(i=0;i<APP_ICON_SIZE;i++)
								*idata++ = icon_data[i];
							count_icon_block = 0;
							num_icon_block_get = 0;
							sio_rdstate++ ;
						}
						
						rx_byte = 1;
						tx_interrupt_rdy = 1;
						tx_command_data = CHECKSUM_OK; // Confirm 20B Block Rx. OK //
						CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
					}
					
				}
				break;
				
            case  4  : /* (B) Get DP's Data and then go to case 7 if get one block size */
				/* (B) That is use for the 2 buffers queue put program data into message queue */
				/* (B) If the download program complete, then goto idle state  */
				
				*sio_buffer_ptr++ = rx_data;
				get_rx_bprog_data++;
				if(get_rx_bprog_data == SIO_BLOCK_SIZE)
				{
					checksum_program_B = 0;
					sio_buffer_ptr -= SIO_BLOCK_SIZE;
					for(i=0; i<SIO_BLOCK_SIZE; i++)
					{
						checksum_program_B += *sio_buffer_ptr++;
						checksum_program_B &= 0xFF;
					}
#ifdef DEBUG
					//Delay(0xff);
					//printf("\n checksum_program_B  = %x", checksum_program_B);
#endif
					
					if( (checksum_program_B & 0x000000FF) == 0 )
					{
						sio_buffer_ptr -= SIO_BLOCK_SIZE;
						
						/* (B) Put the Block into the Message Queue Until Finish */
						
						
						for(i=0; i<FILL_PROG_BOX_TO_MESSAGE_QUEUE; i++)
						{
							*ptr++ = *sio_buffer_ptr++;
							buffer = *(ptr-1);
#ifdef DEBUG
							//printf("\nPtr pointer =%08lx  ===>  data  = %x", ptr-1,buffer);
#endif
							
						}
						
						if(sio_byte_rec++ > 6400)
						{
							CheckPdaPwr();
							sio_byte_rec = 0;
						}
						
						
						
						/* (B) Count get no. of DP's Program block and then */
						/*     go back to IDLE State  when DP finish. */
#ifdef DEBUG
						//printf("\n count_get_prog_block  = %x", count_get_prog_block);
						//printf("\n program_size = %x", program_size);
#endif
						
						if( (count_get_prog_block+1) == program_size )
						{
							/* Program Download Complete and the Go to Idle State */         
#ifdef DEBUG
							printf("\n program_size = %x", program_size);
							printf("\n Download Completed, Thank You");
#endif
							sio_download_driver = 0;
							count_get_prog_block = 0;
							/*
							if(Last_prog_dl == 1)
							{
							sio_rdstate = 0;
							}
							else
							{
							check_num_icon_data = 0;
							sio_rdstate++ ;
							}
							*/
							check_num_icon_data = 0;
							sio_rdstate++ ;
							
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = CHECKSUM_OK; // Confirm 20B Block Rx. OK //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							
						}
						else
						{
							if (sio_buffer_ptr - FILL_PROG_BOX_TO_MESSAGE_QUEUE == buff0)
							{ 
								sio_buffer_ptr = buff1;
							}
							else
							{
								sio_buffer_ptr = buff0;
							}
							
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = CHECKSUM_OK; // Confirm 20B Block Rx. OK //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							count_get_prog_block++;
						}
						
						get_rx_bprog_data = 0;
					}
					else
					{
						/////// Checksum Error , Re-send the 20B ///////
						
						get_rx_bprog_data = 0;
						rx_byte = 1;
						tx_interrupt_rdy = 1;
						tx_command_data = RESEND_BLOCK; // Resend the 20B ( Block Data ) //
						CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
						
						if (sio_buffer_ptr - SIO_BLOCK_SIZE == buff0)
						{
							sio_buffer_ptr = buff1;
						}
						else
						{
							sio_buffer_ptr = buff0;
						}
						
					}
                             }
							 
							 break;
            case  3  : 
#ifdef DEBUG
				//printf("\n rx_data = %x",rx_data);
#endif
				*sio_buffer_ptr++ = rx_data;
				get_rx_bprog_data++;
				if(get_rx_bprog_data == SIO_BLOCK_SIZE)
				{
					checksum_program_B = 0;
					sio_buffer_ptr -= SIO_BLOCK_SIZE;
					for(i=0; i<SIO_BLOCK_SIZE; i++)
					{
						checksum_program_B += *sio_buffer_ptr++;
						checksum_program_B &= 0xFF;
					}
					
#ifdef DEBUG
					//printf("\n CheckSum = %d", checksum_program_B);
#endif
					if( (checksum_program_B & 0x000000FF) == 0 )
					{
						
						for(i=0; i<19; i++)
						{
							drv_name[i]= 0;
						}
						
						sio_buffer_ptr -= SIO_BLOCK_SIZE;
						program_size = 0;
						res_offset = 0;
						prog_code_size = 0;
						
						/* (B) Get DP's attr1 */
						attr1 = *((UBYTE *) sio_buffer_ptr);
#ifdef DEBUG
						printf("\n attr1 = %x", attr1);
#endif
						
						// Get the Program data size //
						for(i=0; i<3; i++ )
						{
							program_size |= ( *(((UBYTE *)sio_buffer_ptr)+i+1) << (i*8) );
						}
						program_size &= 0x00ffffff;                                                      
#ifdef DEBUG
						printf("\n program_size = %x", program_size);
#endif
						
						/* (B) Get DP's IS attr2? */
						attr2 = *(((UBYTE *)sio_buffer_ptr)+4);
#ifdef DEBUG
						printf("\n attr2 = %x", attr2);
#endif
						
						// Get the res_offset //
						for(i=0; i<3; i++ )
						{
							res_offset |= ( *(((UBYTE *)sio_buffer_ptr)+i+5) << (i*8) );
						}
						res_offset &= 0x00ffffff;
#ifdef DEBUG
						printf("\n res_offset = %x", res_offset);
#endif
						
						// Get the prog_code_size //
						for(i=0; i<3; i++ )
						{
							prog_code_size |= ( *(((UBYTE *)sio_buffer_ptr)+i+8) << (i*8) );
						}
						prog_code_size &= 0x000fffff;
#ifdef DEBUG
						printf("\n prog_code_size = %x", prog_code_size);
#endif
						
						/* (B) Get DP's Program Speed */
						download_speed = ( (*((UBYTE *) sio_buffer_ptr+11) & 0xf0) >> 4);
#ifdef DEBUG
						printf("\n Download Speed = %x", download_speed);
#endif
						
						/* (B) Get DP's IS Cut Power? */
						cut_power = ( (*(((UBYTE *)sio_buffer_ptr)+11) & 0x08) >> 3);
#ifdef DEBUG
						printf("\n cut_power = %x", cut_power);
#endif
						
						/* (B) Get DP's IS Last Download Program */
						Last_prog_dl =( (*(((UBYTE *)sio_buffer_ptr)+11) & 0x04) >> 2);
#ifdef DEBUG
						printf("\n Last_prog_dl = %x", Last_prog_dl);
#endif
						
						/* (B) Get DP's IS Last Download Program */
						rot_90_degree =( (*(((UBYTE *)sio_buffer_ptr)+11) & 0x02) >> 1);
#ifdef DEBUG
						printf("\n rot_90_degree = %x", rot_90_degree);
#endif
						
						/* (B) Get DP's Program ID */
						for(i=0; i<19; i++)
						{
							drv_name[i]= *(((UBYTE *)sio_buffer_ptr)+i+13);
						}
						
#ifdef DEBUG
						printf("\n Program ID = %s", drv_name);
#endif
						
						/* (B) Get DP's Program Size and Check is First Time to DP */
						/*     If not the First Time or Memory FULL, Reset and go to IDLE State */
						
						
						/// Now, have "program_id" and "Program Size"( program size == program_size x 20) ///
						/// Then Tx. it to the message Queue to check the program ///
						/// ----ptr----- is a pointer that point the download program location ///
						
						CheckPdaPwr();    
						if ( MemoryInstallProg(drv_name, prog_code_size , attr1, attr2, program_size * 32 -  prog_code_size, res_offset, &appid, &ptr, &pgtbl) != TRUE)
						{
#ifdef DEBUG_ROT
							printf("\nNot first install");
#endif
							///                                        TDelay(0xfff);
							sio_rdstate = 0;
							sio_buffer_ptr = buff0;
							get_rx_bprog_data = 0;
							count_get_prog_block = 0;
							check_prog4b_size = 0;
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = N_FIRST_DOWNLOAD; // fIRST TIME DOWNLOAD //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							if((load_sio_app == 0) && (rot_90_degree == 1))
							{
#ifdef DEBUG_ROT
								printf("\nNot first install but need rot90");
#endif
								load_sio_app = 1;        
								if((NormalOperation == TRUE))
								{
									if(rot_90_degree == 1)
										LcdSetOrientation(1);
									accessory_plug_in = 1;
								}
								else
								{
									
									if(rot_90_degree == 1)
										LcdRot(1);
									accessory_plug_in = 1;
								}
							}
							
							if((sio_rdstate == 0) && (Last_prog_dl == 1))
							{
								SIOPopupRestoreRunningApp();
								sio_appid = 0;
							}
							
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						}
						else
						{
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG
							printf("\nFirst install");
#endif
							if((NormalOperation == TRUE))
							{
#ifdef DEBUG
								printf("\nsio_appid == %d, load_sio_app_not_first == %d",sio_appid,load_sio_app_not_first);
#endif
								if((load_sio_app_not_first == 0) && (sio_appid == 0))
								{
									load_sio_app_not_first = 1;
									Install_complete_flag = 1;
									
#ifdef DEBUG
									printf("\nSerial Download");
#endif
									
#ifdef DEBUG_ROT
									printf("\nFirst install but need rot90 & Normal");
#endif
									sio_appid = 10;
#ifdef DEBUG_APP_LAUNCH
									printf("\n mem install sio_appid = %d",sio_appid);
#endif
									
									//HENRY EvtAppendEvt(EVT_APP_STOP, 0, 0, 0, NULL);
									//HENRY EvtAppendEvt(EVT_APP_LAUNCH, sio_appid, 0, 0, NULL);
									SIOPopupPopup();
									
									if(rot_90_degree == 1)
										LcdSetOrientation(1);
									accessory_plug_in = 1;
								}
								else
								{
									Install_complete_flag = 1;
									
								}
							}
							else
							{
#ifdef DEBUG_ROT
								printf("\nFirst install but need rot90 & Abnormal");
#endif
#ifdef DEBUG_LOAD_APP
								printf("\n not mem Install_complete_flag = %d",Install_complete_flag);
#endif
								Install_complete_flag = 1;       
								if(rot_90_degree == 1)
									LcdRot(1);
								accessory_plug_in = 1;
							}
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							
#ifdef DEBUG
							//                                        printf("\nPorg install address : %08x ", ptr);
#endif
							
							if((sio_rdstate == 0) && (Last_prog_dl == 1))
							{
								SIOPopupRestoreRunningApp();
								sio_appid = 0;
								load_sio_app = 0;
								load_sio_app_not_first = 0;
							}
							
							
							
							sio_download_driver = 1;
							
							sio_rdstate++;
							sio_buffer_ptr = buff0;
							get_rx_bprog_data = 0;
							count_get_prog_block = 0;
							check_prog4b_size = 0;
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = FIRST_DOWNLOAD; // fIRST TIME DOWNLOAD //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
						}
						
                                }
                                else
                                {
                                    /////// Checksum Error , Re-send the 20B ///////
									sio_buffer_ptr = buff0;
									get_rx_bprog_data = 0;
									count_get_prog_block = 0;
									check_prog4b_size = 0;
									rx_byte = 1;
									tx_interrupt_rdy = 1;
									tx_command_data = RESEND_BLOCK; // Resend the 20B ( Block Data ) //
									CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
                                }
                            }
							break;
							
							///////////////////////////////// Handler Case 2 ///////////////////////////////////////////////
							
            case  2  : /* (A) Get Data Size and send it to the Message Queue */
				/* (A) Get Data until finish then go back to IDLE state */
				
				if(acc_data_size < 32)
				{
					// get the Acc. data until finish //
					
					buff0[get_no_rx_data] = rx_data;
#ifdef DEBUG
					printf("\nbuff0[%d] = %x",get_no_rx_data,buff0[get_no_rx_data]);
					printf("\nrx_data = %x",rx_data);
#endif
					get_no_rx_data++;
					if(get_no_rx_data == acc_data_size)
					{
						
						//            KBReadData(buff0[0],buff0[1]);
						//            BYTE *buf;
						//            UWORD i;
						
#ifdef DEBUG
						printf("\nbuff0[0] = %x,buff0[1] = %x",buff0[0],buff0[1]);
#endif
						
						if((NormalOperation != FALSE) && (buff0[1] != 0x10))
						{
							//                                    buf = (BYTE*) pmalloc(35);
							//                                    for(i=0;i<35;i++)
							//                                        buf[i] = buff0[i];
#ifdef DEBUG
							printf("\n call hook mgr");
#endif
							//                                    CheckPdaPwr();
							//                                    CheckEL();
							MsgAppendMsgInt(IntHookMgr, 82, 0, 0, buff0);
						}
						////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						if((NormalOperation == FALSE) && (buff0[1] == 0x10))
						{
							SemiPowerOff = FALSE;
							WakeCpuUp = TRUE;
						}
						else
						{
							if((NormalOperation != FALSE) && (buff0[1] == 0x10))
								MsgAppendMsgInt(IOKeyCtrlMgr, MSG_POWER_REPEAT, POWER_REPEAT_OFF, 0,NULL);
						}
						////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						// Then Put the buff1[] data buffer to the message queue //
						
						if(NormalOperation == FALSE)
							SemiPowerOff = FALSE;
						sio_rdstate = 0;
					}
				}
				else
				{
					// Set a Buffer to get the Acc. data caz the Size too large //
					
					
					// Then Put the rx_acc_data_buff1[] data buffer to the message queue //
					
					
					sio_rdstate = 0;
				}
				
				
				break;
				
				///////////////////////////////// Handler Case 2 END ///////////////////////////////////////////////
				
				
				///////////////////////////////// Handler Case 1 ///////////////////////////////////////////////
				
            case  1  : /* (A) Read the Acc Data and Get Size if > 31 Bytes */
				if( check_get4b_data == 0 )
				{ // program size store no. of Block only, Total Program Size = program_size x 20 ///
					acc_data_size |= ( rx_data << BYTE2 );
					
				}
				if( check_get4b_data == 1 )
				{ // program size store no. of Block only, Total Program Size = program_size x 20 ///
					acc_data_size |= ( rx_data << BYTE3 );
					
				}
				if( check_get4b_data == 2 )
				{ // program size store no. of Block only, Total Program Size = program_size x 20 ///
					acc_data_size |= ( rx_data << BYTE0 );
					
				}
				if( check_get4b_data == 3 )
				{ // program size store no. of Block only, Total Program Size = program_size x 20 ///
					acc_data_size |= ( rx_data << BYTE1 );
					
				}
				
				check_get4b_data++;
				if( check_get4b_data > 3 )
				{
					sio_rdstate++;
					check_get4b_data = 0;
				}
				
				break;
				
				///////////////////////////////// Handler Case 1 END ///////////////////////////////////////////////
				
				
				///////////////////////////////// Handler Case 0 ///////////////////////////////////////////////
				
            case  0  : /* Idle State and check DownLoad Prog.(DP) or Get Acc. Data */
				/* And Handler if First Byte Rx. Error */
				
#ifdef DEBUG_KB
				printf("\nCase 0 Rx. data = %x",rx_data);
#endif
				/*
				count_first_rdy++;
				if( (rx_data == 0x000000ff) && (count_first_rdy<2) )
				{
				break;
				}
				*/
				/*
				{
				rx_byte = 1;
				tx_interrupt_rdy = 1;
				tx_command_data = RESEND_BYTE; // Reset the Accessory all system //
				CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
				}
				*/
				
				
				if( rx_data != 0x00000072 )
				{
					if( (rx_data & 0x00000080 ) != 0x00000080 )
					{
						// Input First Byte Error, Reset Speed and Info. Acc. RESET THE SYSTEM //
#ifdef DEBUG
						//  printf("\nFirst Byte Error");
#endif
						count_rx_error++;
						if (count_rx_error > 3)
						{
							//                                    SIOInit();
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = RESET_ACC_SYS; // Reset the Accessory all system //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
						}
						else
						{
							rx_byte = 1;
							tx_interrupt_rdy = 1;
							tx_command_data = RESEND_BYTE; // Reset the Accessory all system //
							CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
						}
						
					}
					else
					{
						checksum = 1;
						if( (rx_data & 0x00000020) != 0 )
							checksum++;
						if( (rx_data & 0x00000010) != 0 )
							checksum++;
						if( (rx_data & 0x00000008) != 0 )
							checksum++;
						if( (rx_data & 0x00000004) != 0 )
							checksum++;
						if( (rx_data & 0x00000002) != 0 )
							checksum++;
						if( (rx_data & 0x00000001) != 0 )
							checksum++;
						
						if( (checksum % 2) == 0 )
						{
							// Accessory Data Input Handling //
							// And then check the Acc. Data Size //
							
							acc_data_size = ((rx_data >> 1) & 0x0000001f);
							if(acc_data_size == 0)
							{
								sio_rdstate++;
								//                                        acc_data_timer_active = 1;
								//                                        en_acc_data_timer = TmrIntEnableIntPen(5000, (void *)AccDataTimeOut);
								count_rx_error = 0;
								rx_byte = 1;
								tx_interrupt_rdy = 1;
								tx_command_data = DRV_DATA_ACK_OK; // First Byte Return Correct//
								CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							}
							else
							{
								sio_rdstate++;
								sio_rdstate++;
								//                                        acc_data_timer_active = 1;
								//                                        en_acc_data_timer = TmrIntEnableIntPen(5000, (void *)AccDataTimeOut);
								count_rx_error = 0;
								rx_byte = 1;
								tx_interrupt_rdy = 1;
								tx_command_data = DRV_DATA_ACK_OK; // First Byte Return Correct//
								CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
								get_no_rx_data = 0; // Reset the counter get no. of Acc. data //
							}
							
						}
						else
						{
							// Input First Byte Error, Reset Speed and Info. Acc. RESET THE SYSTEM //
#ifdef DEBUG
							//   printf("\nFirst Byte Error");
#endif
							
							count_rx_error++;
							if (count_rx_error > 3)
							{
								//                                        SIOInit();
								rx_byte = 1;
								tx_interrupt_rdy = 1;
								tx_command_data = RESET_ACC_SYS; // Reset the Accessory all system //
								CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							}
							else
							{
								rx_byte = 1;
								tx_interrupt_rdy = 1;
								tx_command_data = RESEND_BYTE; // Reset the Accessory all system //
								CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
							}
						}
					}
				}
				else
				{
					// DownLoad Program Request and then Handling //
					
					CheckPdaPwr();
					
					sio_rdstate++;
					sio_rdstate++;
					sio_rdstate++;
					sio_buffer_ptr = buff0;
					get_rx_bprog_data = 0;
					acc_data_size = 0;
					//                           download_timer_active = 1;
					//                           en_download_timer = TmrIntEnableIntPen(5000, (void *)ProgTimeOut);
					count_rx_error = 0;
					rx_byte = 1;
					tx_interrupt_rdy = 1;
					tx_command_data = DRV_DATA_ACK_OK; // First Byte Return Correct//
					CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
					get_no_rx_data = 0; // Reset the counter get no. of Acc. data //
					program_size = 0;
				}
				break;
				///////////////////////////////// Handler Case 0 END ///////////////////////////////////////////////
        }
		
        for(j=0;j<40;j++) // No Operation --Dummy //
        {
            nop=0;
        }
		
    }
	
    else
    {
        if(tx_interrupt_rdy == 0)
        {
            rx_byte = 1;
            tx_interrupt_rdy = 1;
            CPU->REG_MFIO_DATA_OUT &= 0xDFFFFFFF; // Set Interrupt Active //
        }
        else
        {
            CPU->REG_MFIO_DATA_OUT |= 0x20008000;
            rx_byte = 0;
			
            SIOTransmit(tx_command_data);
			/*
			i=0;
			
			  do
			  {
			  //////////// Put the Data Out and clk Active ////////            
			  output_bit = ((tx_command_data >> i) & 0x00000001);
			  if(output_bit == 0)
			  {
			  CPU->REG_MFIO_DATA_OUT &= 0xFFFF3FFF;
			  CPU->REG_MFIO_DATA_OUT |= 0x00000000;
			  }
			  else
			  {
			  CPU->REG_MFIO_DATA_OUT &= 0xFFFF3FFF;
			  CPU->REG_MFIO_DATA_OUT |= 0x00004000; // set output bit high //
			  }
			  
				//////////// Set the Clk In-Active but Data no Change /////////
                CPU->REG_MFIO_DATA_OUT |= 0x00008000;
				i++;
				}while( i < 8 );
				
			*/
			
            tx_interrupt_rdy = 0;
			
        }
		
        for(j=0;j<100;j++) // No Operation --Dummy //
        {
            nop=0;
        }
		
    }
	
}

/*---------------------------------------------------------------------------
Prototype :   void  TDelay(int count);
Purpose   :   make a delay
Scope     :   ALL
input     :   int count :     how long to delay
return    :   N/A
---------------------------------------------------------------------------*/

void TDelay(int count)
{
    while(count--);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void HwSioInit()
{
	register WORD *CpuReg;
    CpuReg = CPU_IOREG_BASE;
	
    if(accessory_plug_in == 1)      //// the sio plug in ////
    {
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~SIO_PIN_SEL;
		
    }
    else
    {
		
#ifdef DEBUG
		//        printf("\nHwSioInit accessory_not_plug_in");
#endif
		
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_DATA_IN_NO_USE;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
        CpuReg[IOREG_MFIO_POWER_DOWN] |= SIO_CAN_POWER_DOWN_PIN;
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY|SIO_DEVDET_POWER_EN|SIO_DATA_IN_NO_USE);
		
	}
	
}

void HwSioOn()
{
	register WORD *CpuReg;
	CpuReg = CPU_IOREG_BASE;	/* defined in CpuIoReg.h */
	
    if(accessory_plug_in == 1)      //// the sio plug in ////
    {
		
#ifdef DEBUG_SIO_PWR
        printf("\nHwSioOn accessory_plug_in");
#endif
		
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~SIO_PIN_SEL;
		
    }
    else
    {
#ifdef DEBUG_SIO_PWR
        printf("\nHwSioOn accessory_not_plug_in");
#endif
		
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_DATA_IN_NO_USE;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
        CpuReg[IOREG_MFIO_POWER_DOWN] |= SIO_CAN_POWER_DOWN_PIN;
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY|SIO_DEVDET_POWER_EN|SIO_DATA_IN_NO_USE);
		
    }
	
}

void HwSioOff()
{
	register WORD *CpuReg;
    CpuReg = CPU_IOREG_BASE;    /* defined in CpuIoReg.h */
	
    if(accessory_plug_in == 1)      //// the sio plug in ////
    {
#ifdef DEBUG_SIO_PWR
        printf("\nHwSioOff accessory_plug_in");
#endif
		
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~(SIO_DATA_IN_NO_USE);
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~SIO_PIN_SEL;
		
    }
    else
    {
#ifdef DEBUG_SIO_PWR
        printf("\nHwSioOff accessory_not_plug_in");
#endif
		
        CpuReg[IOREG_MFIO_SEL       ] |= SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_PIN_DIRECTION;
		
        CpuReg[IOREG_MFIO_DIRECTN   ] |= SIO_DATA_IN_NO_USE;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_PIN_SEL;
        CpuReg[IOREG_MFIO_DATA_OUT  ] |= SIO_OUT_PIN;
        CpuReg[IOREG_MFIO_DATA_OUT  ] &= ~SIO_CUT_POWER;      
		
		
		
        CpuReg[IOREG_MFIO_POWER_DOWN] |= SIO_CAN_POWER_DOWN_PIN;
        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY);
		//        CpuReg[IOREG_MFIO_POWER_DOWN] &= ~(SIO_CS|SIO_DEVDET|SIO_RDY|SIO_DEVDET_POWER_EN|SIO_DATA_IN_NO_USE);
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
