           /****************************
            *                          *
            *       INCLUDE FILES      *
            *                          *
            ****************************/

#ifndef _EMU_COMM_
#include "emucomm.h"
#endif
#ifndef _COMM_DATA_
#include "commdata.h"
#endif
//#ifndef
//#endif


           /****************************
            *                          *
            *     LOCAL DEFINITIONS    *
            *                          *
            ****************************/

            /****************************
             *                          *
             *    EXTERNAL VARIABLES    *
             *                          *
             ****************************/
void CmdTest(void);

            /****************************
             *                          *
             *     LOCAL PROTOTYPES     *
             *                          *
             ****************************/

void DebugIceEntry(void) ;
U8   GetCmdStream(void);
U8   CheckCommand(U8 * , U8 * ) ;
void ShowMsg(U8 MsgNum) ;
void ShowSpace(U8 num);
void ShowNextLine(void);
void ShowOneByte(U8 value);
void ShowOneWord(U8 *WordPtr);
U8   GetToken(void);
U8   ShowReg(void) ;
void ShowAllReg(void);
U8   CheckReg(U8 * ,U8 * ) ;
U8   Token2Word(U8 *Addr) ;
U8   ShowMemByte(void);
U8   ShowMemHalfWord(void);
U8   ShowMemWord(void);
U8   ShowWord(U8 *DataBuff,U16 len) ;
U8  ShowFillByteMem(void) ;
U8  ShowFillWordMem(void) ;
void SwapWord(U8 *WordPtr) ;

U8   ReadReg(U8 reg_num,U8 *value) ;
U8   DumpByteMem(U16 DumpAddrL,U16 DumpAddrH,U16 DumpLen,U8 *DumpBuffPtr);
U8   DumpWordMem(U16 DumpAddrL,U16 DumpAddrH,U16 DumpLen,U8 *DumpBuffPtr);
U8   FillByteMem(U16 DumpAddrL,U16 DumpAddrH,U16 DumpLen,U8 *DumpBuffPtr);
U8   FillWordMem(U16 DumpAddrL,U16 DumpAddrH,U16 DumpLen,U8 *DumpBuffPtr);
U8   EpHalt(void);
U8   EpGo(void);



            /****************************
             *                          *
             *      EXECUTABLE CODE     *
             *                          *
             ****************************/

//    Debug command define



U8 CmdStream[100],Token[100] ;


/***************************************************************************
**
** DebugIceEntry
**
**  Description: For debug Ice system
**
**  Parameters:  none
**
****************************************************************************/
void DebugIceEntry(void){

     U8 CmdNum;

    ShowMsg(1);     // 1 : show the mode title
    while(1)
    {

         if ( GetCmdStream() )  continue ;  // 1 : esc
         if ( GetToken() ) {
                ShowMsg(0);     // 0 :  cmd err
                continue ;
         }
         CheckCommand(&Token,&CmdNum);
         switch(CmdNum)
         {
             case  0 :  //  rd
                ShowReg() ;
                break ;
             case  1 :
                break ;
             case  4 :
                ShowMemByte() ;
                break ;
             case  5 :
                ShowMemHalfWord() ;
                break ;
             case  6 :
                ShowMemWord() ;
                break ;
             case  7 :
                ShowFillByteMem();
                break ;
             case  8 :
//!!!!!                ShowFillHalfWordMem();
                break ;
             case  9 :
                ShowFillWordMem();
                break ;
             case  12 :
                EpHalt() ;
                break;
             case  13 :
                EpGo();
                break ;
             default :
                ShowMsg(0) ;
                break ;
         }

    }


}

/***************************************************************************
**
** ShowMem byte,half word,word
**
**  Parameters:
****************************************************************************/
U8 ShowMemByte(void)
{   U8 DumpAddr[4],DumpBuff[256],err;
    U16 DumpLen,*temp ;
    err=GetToken() ;
    if ( err )  return(1) ;
    err=Token2Word(DumpAddr) ;
    SwapWord(DumpAddr);
    if ( err ) { ShowMsg(3); return(1) ; }
    DumpLen=256 ;
    temp =(U16 *) DumpAddr ;
    DumpByteMem( *temp,*(temp+1),DumpLen,DumpBuff) ;
    ShowWord(DumpBuff,256/4) ;
}
U8 ShowMemWord(void)
{   U8 DumpAddr[4],DumpBuff[300],err;
    U16 DumpLen,*temp ;
    err=GetToken() ;
    if ( err )  return(1) ;
    err=Token2Word(DumpAddr) ;
    SwapWord(DumpAddr);
    if ( err ) { ShowMsg(3); return(1) ; }
    DumpLen=256/4 ;
    temp =(U16 *) DumpAddr ;
    DumpWordMem( *temp,*(temp+1),DumpLen,DumpBuff) ;
    ShowWord(DumpBuff,256/4) ;
}
/***************************************************************************
**
** FillMem  Byte, half word , word
**
**  Parameters:
****************************************************************************/
U8  ShowFillByteMem(void)
{
    U8 FillAddr[4],FillBuff[256],err;
    U16 FillLen,*temp;

    FillLen = 1 ;
    err=GetToken() ;
    if ( err )  return(1) ;
    err=Token2Word(FillAddr) ;
    SwapWord(FillAddr);
    if ( err ) { ShowMsg(3); return(1) ; }
    //cnt=0 ;
    //for (;;)
    //{
        err=GetToken() ;
        if ( err )  return(1) ;
        err=Token2Word(FillBuff) ;
        SwapWord(FillBuff);
        if ( err ) { ShowMsg(4); return(1) ; }
    //    cnt = cnt + 4 ;
    //}
    temp =(U16 *) FillAddr ;
    FillByteMem( *temp,*(temp+1),FillLen,FillBuff) ;

}
U8  ShowFillWordMem(void)
{
//    U8 FillAddr[4],FillBuff[256],err,cnt;
    U8 FillAddr[4],FillBuff[32],err;
    U16 FillLen,*temp ;
    FillLen = 1 ;
    err=GetToken() ;
    if ( err )  return(1) ;
    err=Token2Word(FillAddr) ;
    SwapWord(FillAddr);
    if ( err ) { ShowMsg(3); return(1) ; }
    //cnt=0 ;
    //for (;;)
    //{
        err=GetToken() ;
        if ( err )  return(1) ;
        err=Token2Word(FillBuff) ;
        SwapWord(FillBuff);
        if ( err ) { ShowMsg(4); return(1) ; }
    //    cnt = cnt + 4 ;
    //}
    temp =(U16 *) FillAddr ;
    FillWordMem( *temp,*(temp+1),FillLen,FillBuff) ;

}


/***************************************************************************
**
** ShowReg
**
**  Parameters:
**
****************************************************************************/
U8 ShowReg(void)
{
    U8 value[4],err,RegNum;
    if ( GetToken() ) {   // show all reg
       ShowAllReg();
    }
    else{
       err = CheckReg(&Token,&RegNum) ;
       if ( err ) {
            ShowMsg(2) ;
            return(1) ;
       }
       ReadReg(RegNum,value);
       TransmitByte(':');
       ShowOneWord(value);
       ShowNextLine();
    }
    return(0) ;
}
/***************************************************************************
**
** GetCmdStream
**
**  Description:
**
**  Parameters:
**     output : U16 err
**
****************************************************************************/
U8 GetCmdStream()
{
U8  Counter=0,ch ;
    for (;;){
       SetDmaCount(1);
       ch=ReceiveByte() ;
       if (!timeOut) CmdStream[Counter++]=ch;
       else continue ;
       if ( Counter == 0x80 ) TransmitByte(07);
       if ( Counter == 0x80 ) break ;

       if ( ch == 13 )    break ;
       if ( ch == 27 )    { ShowNextLine ; return(1) ; }
    }
    CmdStream[--Counter]='\0' ;
    ShowNextLine();
    return(0) ;
}


/***************************************************************************
**
** DbgBdm860Go
**
**  Description:
**
**  Parameters:
**     output : U16 err
**
****************************************************************************/
//void DbgBdm860Go()
//{
//}
/***************************************************************************
**
** DbgBdm860Halt
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
****************************************************************************/
/***************************************************************************
**
** DbgBdm860Register
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
****************************************************************************/
/***************************************************************************
**
** DbgBdm860Step
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
****************************************************************************/
/***************************************************************************
**
** FunctionName
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
****************************************************************************/




/***************************************************************************
**
**  Miscellanea function
**
****************************************************************************/
void ShowSpace(U8 num)
{
    U8  cnt;
    for (cnt=0;cnt<num;cnt++)
        TransmitByte(' ');
}
void ShowNextLine(void)
{
    TransmitByte(13);
    TransmitByte(10);
}
void ShowOneByte(U8 value)
{
    U8  cnt,temp = value  ;
    value = value >> 4 ;
    for (cnt=0 ; cnt < 2 ; cnt ++ ){
        if (  value < 10  )     value=value+'0' ;
        else                    value=value-10+'A' ;
        TransmitByte(value) ;
        value = temp ;
        value = value & 0x0f ;
    }
}
void ShowOneWord(U8 *WordPtr)
{
    U8 cnt;
    for (cnt=0;cnt<4;cnt++){
        ShowOneByte(WordPtr[cnt]) ;
    }
}

U8 GetToken(void)
{
  U8    cnt=0,cnt1=0;
  for (;;){
        if(CmdStream[cnt] == 0  )     return(1) ;  // error
        if(CmdStream[cnt] == ' ')     cnt++ ;
        else                          break ;
  }
  for(;;){
        if ((CmdStream[cnt] == ' ')||(CmdStream[cnt] == 0 ))  break ;
                Token[cnt1++]=CmdStream[cnt++] ;
        if ( (Token[cnt1-1] >= 'a') && (Token[cnt1-1] <= 'z') )
            Token[cnt1-1] = Token[cnt1-1] - 'a' + 'A' ;  // let it always been upper
        CmdStream[cnt-1]=' ' ;
  }
  Token[cnt1] = 0 ;
  return(0) ;
}
U8  ShowWord(U8 *DataBuff,U16 len)
{   U8 cnt,cnt1;
    for (cnt=0; cnt < (len/4) ; cnt++ )
    {
        for(cnt1=0; cnt1<4 ; cnt1++ )
        {
          ShowOneWord(DataBuff) ;
          ShowSpace(2);
          DataBuff+=4 ;
        }
        ShowNextLine();
    }
    return GOOD;
}

U8  Token2Word(U8 *Addr)
{   U8  cnt,value,flag ;

    Addr[0]=0 ;
    Addr[1]=0 ;
    Addr[2]=0 ;
    Addr[3]=0 ;
    for(cnt=0;;)
    {
        flag = 0 ;
        if ( Token[cnt] == 0 ) return(0) ;
        if ( (cnt == 8 ) && ( Token[cnt] != 0 ) ) return(1) ;
        if ( (Token[cnt] >= '0') && ( Token[cnt] <= '9' ) )
           { value=Token[cnt] - '0' ; flag = 1 ; }
        if ( (Token[cnt] >= 'A') && ( Token[cnt] <= 'F' ) )
           { value=Token[cnt] - 'A' + 10 ; flag = 1 ; }
        if (!flag) return(1) ;
        cnt++ ;
        Addr[3]=Addr[3] << 4 ;
        Addr[3]=Addr[3] | ( Addr[2] >> 4 ) ;
        Addr[2]=Addr[2] << 4 ;
        Addr[2]=Addr[2] | ( Addr[1] >> 4 ) ;
        Addr[1]=Addr[1] << 4 ;
        Addr[1]=Addr[1] | ( Addr[0] >> 4 ) ;
        Addr[0]=Addr[0] << 4 ;
        Addr[0]=Addr[0] | value  ;
    }
    return(0);


}

void SwapWord(U8 *WordPtr)
{
    U8 temp ;

    temp=WordPtr[0] ;
    WordPtr[0]=WordPtr[3] ;
    WordPtr[3]=temp ;
    temp=WordPtr[1] ;
    WordPtr[1]=WordPtr[2] ;
    WordPtr[2]=temp ;

}
