#include "emucomm.h"
#include "emullfw.h"
#include "emutest.h"
#include <string.h>

U8  *bin2hex;

void SendTitle(void)
{ U8 DBUG_TITLE[]={13,10,'W','e','l','c','o','m','e',' ',
                   't','o',' ','M','I','C','E',' ',
                   'D','e','b','u','g',' ','S','y','s','t','e','m',13,10,
                   'M','I','C','R','O','T','E','K',' ',
                   'I','n','t','e','r','n','a','t','i','o','n','a','l',' ',
                   'I','n','c','.',0};
  PutStr(DBUG_TITLE);
}

void SendDigit(U16 t)
{ U8 s[8];
  int i;
  s[0]=bin2hex[t%10];
  s[1]='.';
  s[2]=bin2hex[(t/=10)%10];
  for(i=3;t/=10;i++)
    s[i]=bin2hex[t%10];
  while(i)
    TransmitByte(s[--i]);
}

void SendTime(U16 t)
{
  TransmitByte('W');
  TransmitByte('r');
  TransmitByte('i');
  TransmitByte('t');
  TransmitByte('e');
  TransmitByte('/');
  TransmitByte('V');
  TransmitByte('e');
  TransmitByte('r');
  TransmitByte('i');
  TransmitByte('f');
  TransmitByte('y');
  TransmitByte('/');
  TransmitByte('R');
  TransmitByte('e');
  TransmitByte('t');
  TransmitByte('r');
  TransmitByte('y');
  TransmitByte(' ');
  TransmitByte('1');
  TransmitByte('2');
  TransmitByte('8');
  TransmitByte('K');
  TransmitByte(' ');
  TransmitByte('B');
  TransmitByte('y');
  TransmitByte('t');
  TransmitByte('e');
  TransmitByte(' ');
  TransmitByte('i');
  TransmitByte('n');
  TransmitByte(' ');
  SendDigit((t+1) >> 1);
  TransmitByte('s');
  TransmitByte('e');
  TransmitByte('c');
  TransmitByte(' ');
  TransmitByte('(');
  SendDigit(1500/t);
  TransmitByte('M');
  TransmitByte('B');
  TransmitByte('/');
  TransmitByte('m');
  TransmitByte(')');
  TransmitByte(13);
  TransmitByte(10);
}

void TestCmd(U8 *Cmd)
{ char Str0[]={'R','S','T','H',0};
  char Str1[]={'R','S','T','L',0};
  char Str2[]={'T','E','A','H',0};
  char Str3[]={'T','E','A','L',0};
  char Str4[]={'B','K','P','H',0};
  char Str5[]={'B','K','P','L',0};
  char *CmdStr[]={Str0,Str1,Str2,Str3,Str4,Str5,0};
  U16  CmdWord[]={0xFF80,0x7F00, 0xFF40,0xBF00, 0xFF01,0xFE00};
  char StrTBDM[]={'T','B','D','M',0};
  char StrTRST[]={'T','R','S','T',0};
  char StrDRST[]={'D','R','S','T',0};
  char StrTBUF[]={'T','B','U','F',0};
  char StrDBUF[]={'D','B','U','F',0};
  char StrRST[]={'R','E','S','E','T',0};
  char StrREG[]={'R','E','G',0};
  char StrCMPB[]={'C','M','P','B',0};
  char StrCMPW[]={'C','M','P','W',0};
  char StrCPYp[]={'C','P','Y','+',0};
  char StrCPYm[]={'C','P','Y','-',0};
  char StrSearch[]={'S','E','A','R','C','H',0};
  char BDMerr[]={'B','D','M','e','r','r',0};
  char FillOK[]={'F','i','l','l',' ','C','o','m','p','l','e','t','e',0};
  char TestOK[]={'T','e','s','t',' ','C','o','m','p','l','e','t','e',0};
  char CmdAbort[]={'A','B','O','R','T',0};
  char StrEPBK[]={'E','P','B','K',0};

  U8 MemBuff[128],*str;

  U8 h,l;
  U32 BDMbuf;
  U16 delta;
  int i;

  for(l=0;CmdStr[l];l++)
    if(strcmp(Cmd,CmdStr[l])==0)
      if((l==4)||(l==5))
      { TestEP(CmdWord[l]);
        return; }
      else
      { TestP2(CmdWord[l]);
        return; }
  if(strcmp(Cmd,StrTBDM)==0)
    TraceBDM();
  else if(strcmp(Cmd,StrDRST)==0)
    BDMTraceReset();
  else if(strcmp(Cmd,StrTRST)==0)
  {
    TraceReset();
    TraceEnable();
  }
  else if(strcmp(Cmd,StrTBUF)==0)
    DumpTraceBuff();
  else if(strcmp(Cmd,StrDBUF)==0)
    DumpDebugBuff();
  else if(strcmp(Cmd,StrEPBK)==0)
  {

      TransmitByte('E');
      HexByteStr('=',&exceptBreak);
      TransmitByte(',');
      TransmitByte('A');
      TransmitByte('1');
      HexLongStr('=',BDMTempB);
      TransmitByte(',');
      TransmitByte('D');
      TransmitByte('1');
      HexWordStr('=',BDMTempB+6);
      TransmitByte(',');
      TransmitByte('A');
      TransmitByte('2');
      HexLongStr('=',BDMTempB+8);
      TransmitByte(',');
      TransmitByte('D');
      TransmitByte('2');
      HexWordStr('=',BDMTempB+14);
      TransmitByte(13);
      TransmitByte(10);
  }
  else if(strcmp(Cmd,StrREG)==0)
    TestReg(MemBuff);
  else if(strcmp(Cmd,StrSearch)==0)
    TestSearch();
  else if(strcmp(Cmd,StrCMPB)==0)
    TestCmp(0);
  else if(strcmp(Cmd,StrCMPW)==0)
    TestCmp(1);
  else if(strcmp(Cmd,StrCPYp)==0)
    TestCpy(0);
  else if(strcmp(Cmd,StrCPYm)==0)
    TestCpy(1);
  else if(*Cmd=='E')
    EditReg(Cmd+1);
  else if((*Cmd=='M')&&(Cmd[1]=='R'))
  {
    if(Cmd[2]==0)
    {
      SetMaxRetry(l=SetMaxRetry(0));
      HexByteStr('=',(U8*)&l);
      TransmitByte(13);
      TransmitByte(10);
    }
    else if(hex2bin(Cmd+2,&l))
      SendHexErr();
    else
      SetMaxRetry(l);
  }
  else if((*Cmd=='T')&&(Cmd[1]=='R'))
  {
    if(hex2long(Cmd+2,(U8*)&BDMbuf))
      SendHexErr();
    else for(;;)
    { delta=Clock;
      for(i=0;i<0x200;i++,BDMbuf+=0x80)
      {
        HexLongStr(13,(U8*)&BDMbuf);
        if(l=TestMem(BDMbuf,0,128,1))
        {
          TransmitByte(' ');
          if(l==2)
            PutStr(BDMerr);
          SendVerifyErr();
          return;
        }
      }
      delta-=Clock;
      BDMbuf-=2;
      HexLongStr(13,(U8*)&BDMbuf);
      BDMbuf+=2;
      TransmitByte(' ');
      PutStr(TestOK);
      SendTime(delta);
    }
  }
  else if((*Cmd=='T')&&((Cmd[1]=='W')||(Cmd[1]=='B')))
  {
    if(hex2long(Cmd+2,(U8*)&BDMbuf))
      SendHexErr();
    else
    { delta=Clock;
      for(i=0;i<0x200;i++,BDMbuf+=0x80)
      {
        HexLongStr(13,(U8*)&BDMbuf);
        if(l=TestMem(BDMbuf,0,128,(Cmd[1]=='B')?0:1))
        {
          TransmitByte(' ');
          if(l==2)
            PutStr(BDMerr);
          SendVerifyErr();
          return;
        }
      }
      delta-=Clock;
      BDMbuf-=((Cmd[1]=='B')?1:2);
      HexLongStr(13,(U8*)&BDMbuf);
      TransmitByte(' ');
      PutStr(TestOK);
      SendTime(delta);
    }
  }
  else if((*Cmd=='D')&&(Cmd[1]=='B'))
  {
    if(hex2long(Cmd+2,(U8*)&BDMbuf))
      SendHexErr();
    else
    {
      if(DumpByteMem(BDMbuf,0,128,MemBuff))
        PutStr(BDMerr);
      for(h=0;h<128;h+=16,BDMbuf+=16)
      {
        HexLongStr(0,(U8*)&BDMbuf);
        TransmitByte(':');
        for(l=h;l<(h+(U8)16);l++)
          HexByteStr(' ',MemBuff+l);
        asciiStr(MemBuff+h);
      }
    }
  }
  else if(*Cmd=='D')
  {
    if(Cmd[1]=='W')
    {
      if(hex2long(Cmd+2,(U8*)&BDMbuf))
      {
        SendHexErr();
        return;
      }
    }
    else if(hex2long(Cmd+1,(U8*)&BDMbuf))
    {
        SendHexErr();
        return;
    }
    if(DumpWordMem(BDMbuf,0,128,MemBuff))
      PutStr(BDMerr);
    for(h=0;h<128;h+=16,BDMbuf+=16)
    {
      HexLongStr(0,(U8*)&BDMbuf);
      TransmitByte(':');
      for(l=h;l<(h+(U8)16);l+=2)
        HexWordStr(' ',MemBuff+l);
      asciiStr(MemBuff+h);
    }
  }
  else if((*Cmd=='W')&&(Cmd[1]=='C'))
  {
    if(hex2long(Cmd+2,(U8*)&BDMbuf))
      SendHexErr();
    else
    {
      if(l=FillCode(BDMbuf))
      {
        if(l==2)
          PutStr(BDMerr);
        SendVerifyErr();
      }
      else
        PutStr(FillOK);
    }
  }
  else if((*Cmd=='F')&&(Cmd[1]=='B'))
  {
    if(hex2long(Cmd+2,(U8*)&BDMbuf))
      SendHexErr();
    else
    { l=0;
      TransmitByte('S');
      TransmitByte('t');
      TransmitByte('r');
      TransmitByte('i');
      TransmitByte('n');
      TransmitByte('g');
      TransmitByte(':');
      TransmitByte(' ');
      if(str=GetStr(0))
        for(l=0;str[l];l++)
          MemBuff[l]=str[l];
      else
      {
        PutStr(CmdAbort);
        return;
      }
      if(l==0)
        for(l=0;l<2;l++)
          MemBuff[l]=0;
      if(l=FillByteMem(BDMbuf,0,128,l,MemBuff,1))
      {
        if(l==2)
          PutStr(BDMerr);
        SendVerifyErr();
      }
      else
        PutStr(FillOK);
    }
  }
  else if(*Cmd=='F')
  {
    if(hex2long(Cmd+1,(U8*)&BDMbuf))
      SendHexErr();
    else
    { l=0;
      TransmitByte('S');
      TransmitByte('t');
      TransmitByte('r');
      TransmitByte('i');
      TransmitByte('n');
      TransmitByte('g');
      TransmitByte(':');
      TransmitByte(' ');
      if(str=GetStr(0))
        for(l=0;str[l];l++)
          MemBuff[l]=str[l];
      else
      {
        PutStr(CmdAbort);
        return;
      }
      if(l==0)
        for(l=0;l<2;l++)
          MemBuff[l]=0;
      else if(l&1)
        MemBuff[l++]=0;
      if(l=FillWordMem(BDMbuf,0,128,l,MemBuff,1))
      {
        if(l==2)
          PutStr(BDMerr);
        SendVerifyErr();
      }
      else
        PutStr(FillOK);
    }
  }
  else if((*Cmd=='S')&&(Cmd[1]=='L'))
  {
    if(hex2long(Cmd+2,MemBuff))
      SendHexErr();
    else
    {
      TestBDMLong(MemBuff);
      TransmitByte('R');
      TransmitByte(bin2hex[15&MemBuff[6]]);
      HexByteStr(0,MemBuff+5);
      HexByteStr(0,MemBuff+4);
      TransmitByte(13);
      TransmitByte(10);
      TransmitByte('R');
      TransmitByte(bin2hex[15&MemBuff[2]]);
      HexByteStr(0,MemBuff+1);
      HexByteStr(0,MemBuff);
      TransmitByte(13);
      TransmitByte(10);
    }
  }
  else if(*Cmd=='S')
  {
    if(hex2bin(Cmd+1,&h)||hex2bin(Cmd+3,&l))
      SendHexErr();
    else
    {
      BDMbuf=(h<<8)+l;
      TestBDM(&BDMbuf);
      TransmitByte('R');
      TransmitByte(bin2hex[15&(BDMbuf>>16)]);
      TransmitByte(bin2hex[15&(BDMbuf>>12)]);
      TransmitByte(bin2hex[15&(BDMbuf>>8)]);
      TransmitByte(bin2hex[15&(BDMbuf>>4)]);
      TransmitByte(bin2hex[BDMbuf&15]);
      TransmitByte(13);
      TransmitByte(10);
    }
  }
  else if((*Cmd=='A')&&((Cmd[1]=='L')||(Cmd[1]=='H')||(Cmd[1]=='W')))
  { delta=0;
    if(hex2bin(Cmd+2,&h)||hex2bin(Cmd+4,&l))
      SendHexErr();
    else for(;;)
    { SetDmaCount(1);
      BDMbuf=(h<<8)+l;
      if(Cmd[1]=='L')
        TestBDM_L(&BDMbuf);
      else if(Cmd[1]=='H')
        TestBDM_H(&BDMbuf);
      else
        TestBDM(&BDMbuf);
      TransmitByte('R');
      TransmitByte(bin2hex[15&(BDMbuf>>16)]);
      TransmitByte(bin2hex[15&(BDMbuf>>12)]);
      TransmitByte(bin2hex[15&(BDMbuf>>8)]);
      TransmitByte(bin2hex[15&(BDMbuf>>4)]);
      TransmitByte(bin2hex[BDMbuf&15]);
      TransmitByte(' ');
      TransmitByte('(');
      TransmitByte(bin2hex[15&(delta>>16)]);
      TransmitByte(bin2hex[15&(delta>>12)]);
      TransmitByte(bin2hex[15&(delta>>8)]);
      TransmitByte(bin2hex[15&(delta>>4)]);
      TransmitByte(bin2hex[delta&15]);
      delta++;
      TransmitByte(')');
      TransmitByte(13);
      TransmitByte(10);
      if(ReceiveByte()==' ')
        return;
    }
  }
  else if((*Cmd=='H')||(*Cmd=='h')||(*Cmd=='?'))
    HelpMsg();
  else if(strcmp(Cmd,StrRST)==0)
  {
    TransmitByte('W');
    TransmitByte('R');
    TransmitByte('O');
    TransmitByte('M');
    TransmitByte('"');
    TransmitByte(']');
    TransmitByte(']');
    TransmitByte('"');
    TransmitByte(',');
    TransmitByte('D');
    TransmitByte('B');
    TransmitByte('U');
    TransmitByte('G');
    TransmitByte('"');
    TransmitByte('_');
    TransmitByte('_');
    TransmitByte('"');
    TransmitByte(13);
    TransmitByte(10);
    SetWatchDog(12);
    for(timeOut=0;timeOut==0;);
    FwReset();
  }
  else
  {
    TransmitByte('?');
    TransmitByte(7);
    TransmitByte(13);
    TransmitByte(10);
  }
}

void EngTest(void)
{ U8 *Cmd;
  U8 HexStr[]={'0','1','2','3','4','5','6','7',
               '8','9','A','B','C','D','E','F'};
  bin2hex=HexStr;
  SetWatchDog(100);
  for(timeOut=0;timeOut==0;);
  SendTitle();
//for(;;)
//{
//  SetWatchDog(1);
//  for(timeOut=0;timeOut==0;);
//  TransmitByte(0x55);
//}
  for(;;)
  {
    TransmitByte('>');
    if(Cmd=GetStr(1))
      TestCmd(Cmd);
  }
}

void PutStr(U8 *Str)
{ if(Str)
    while(*Str)
      TransmitByte(*Str++);
  TransmitByte(13);
  TransmitByte(10);
}

void asciiStr(U8 *Buff)
{ int i;
  TransmitByte(' ');
  for(i=0;i<16;i++)
    if(isprint(Buff[i]))
      TransmitByte(Buff[i]);
    else
      TransmitByte('.');
  TransmitByte(13);
  TransmitByte(10);
}

U8 *GetStr(U8 flag)
{ int i=0;
  static U8 buf[GetStrBufSize+1];
  U8 c;
  for(;;)
  {
    SetDmaCount(1);
    c=ReceiveByte();
    if(timeOut)
      continue;
    if(c==27)
    { TransmitByte('\\');
      TransmitByte(13);
      TransmitByte(10);
      return 0; }
    else if(c==13)
    { TransmitByte(13);
      TransmitByte(10);
      buf[i]=0;
      return buf; }
    else if(c==8)
    { if(i==0)
        TransmitByte(7);
      else
      { i--;
        TransmitByte(8); }}
    else if(i==GetStrBufSize)
      TransmitByte(7);
    else if(flag==0)
      TransmitByte(buf[i++]=c);
    else if(('a'<=c)&&(c<='z'))
      TransmitByte(buf[i++]=(c+=('A'-'a')));
    else
      TransmitByte(buf[i++]=c);
  }
}

U16 hex2bin(U8 *hex,U8 *bin)
{ if(('0'<=hex[0])&&(hex[0]<='9'))
    *bin=(U8)(hex[0]-'0');
  else if(('A'<=hex[0])&&(hex[0]<='F'))
    *bin=(U8)(hex[0]-'A'+10);
  else if(('a'<=hex[0])&&(hex[0]<='f'))
    *bin=(U8)(hex[0]-'a'+10);
  else
    return 1;
  *bin=(U8)((*bin)<<4);
  if(('0'<=hex[1])&&(hex[1]<='9'))
    *bin+=(hex[1]-'0');
  else if(('A'<=hex[1])&&(hex[1]<='F'))
    *bin+=(hex[1]-'A'+10);
  else if(('a'<=hex[1])&&(hex[1]<='f'))
    *bin+=(hex[1]-'a'+10);
  else
    return 1;
  return 0;
}

U16 hex2long(U8 *hex,U8 *bin)
{
 return(hex2bin(hex  ,bin+3)||
        hex2bin(hex+2,bin+2)||
        hex2bin(hex+4,bin+1)||
        hex2bin(hex+6,bin));
}

U16 hex2word(U8 *hex,U8 *bin)
{
 return(hex2bin(hex  ,bin+1)||
        hex2bin(hex+2,bin));
}

void SendHexErr(void)
{
  TransmitByte('H');
  TransmitByte('e');
  TransmitByte('X');
  TransmitByte('E');
  TransmitByte('r');
  TransmitByte('r');
  TransmitByte(7);
  TransmitByte(13);
  TransmitByte(10);
}

void SendVerifyErr(void)
{ int i;
  TransmitByte('V');
  TransmitByte('e');
  TransmitByte('r');
  TransmitByte('i');
  TransmitByte('f');
  TransmitByte('y');
  TransmitByte(' ');
  TransmitByte('E');
  TransmitByte('r');
  TransmitByte('r');
  TransmitByte('o');
  TransmitByte('r');
  TransmitByte(' ');
  TransmitByte('a');
  TransmitByte('t');
  TransmitByte(' ');
  for(i=4;i>0;i--)
  { TransmitByte(bin2hex[BDMTempB[i-1]>>4]);
    TransmitByte(bin2hex[BDMTempB[i-1]&15]); }
  TransmitByte(' ');
  TransmitByte('(');
  TransmitByte('R');
  TransmitByte(':');
  for(i=2;i>0;i--)
  { TransmitByte(bin2hex[BDMTempB[i+3]>>4]);
    TransmitByte(bin2hex[BDMTempB[i+3]&15]); }
  TransmitByte(',');
  TransmitByte('W');
  TransmitByte(':');
  for(i=2;i>0;i--)
  { TransmitByte(bin2hex[BDMTempB[i+5]>>4]);
    TransmitByte(bin2hex[BDMTempB[i+5]&15]); }
  TransmitByte(')');
  TransmitByte(13);
  TransmitByte(10);
}

void HexByteStr(U8 ch,U8 *buff)
{
  if(ch)
    TransmitByte(ch);
  TransmitByte(bin2hex[buff[0]>>4]);
  TransmitByte(bin2hex[buff[0]&15]);
}

void HexWordStr(U8 ch,U8 *buff)
{ int i;
  if(ch)
    TransmitByte(ch);
  for(i=0;i<2;i++)
  {
    TransmitByte(bin2hex[buff[i]>>4]);
    TransmitByte(bin2hex[buff[i]&15]);
  }
}

void HexLongStr(U8 ch,U8 *buff)
{ int i;
  if(ch)
    TransmitByte(ch);
  for(i=4;i>0;i--)
  {
    TransmitByte(bin2hex[buff[i-1]>>4]);
    TransmitByte(bin2hex[buff[i-1]&15]);
  }
}

void TestReg(U8* buff)
{ int i;
  GetReg((U32*)buff);

  TransmitByte('A');
  TransmitByte('n');
  TransmitByte(':');
  for(i=0;i<7;i++)
    HexLongStr(' ',buff+i*4);
  TransmitByte(13);
  TransmitByte(10);

  TransmitByte('D');
  TransmitByte('n');
  TransmitByte(':');
  for(i=7;i<15;i++)
    HexLongStr(' ',buff+i*4);
  TransmitByte(13);
  TransmitByte(10);

  TransmitByte('S');
  TransmitByte('P');
  TransmitByte(':');
  HexLongStr(0,buff+15*4);
  TransmitByte(' ');

  TransmitByte('S');
  TransmitByte('R');
  TransmitByte(':');
  HexLongStr(0,buff+16*4);
  TransmitByte(' ');

  TransmitByte('P');
  TransmitByte('C');
  TransmitByte(':');
  HexLongStr(0,buff+17*4);
  TransmitByte(' ');

  TransmitByte('V');
  TransmitByte('B');
  TransmitByte('R');
  TransmitByte(':');
  HexLongStr(0,buff+18*4);
  TransmitByte(13);
  TransmitByte(10);
}

U16 GetRegNum(U8 *RegName)
{ U8 StrSP[]={'S','P',0};
  U8 StrSR[]={'S','R',0};
  U8 StrPC[]={'P','C',0};
  U8 StrVBR[]={'V','B','R',0};
  U8 StrCSR[]={'C','S','R',0};
  U8 StrAABR[]={'A','A','B','R',0};
  U8 StrTDR[]={'T','D','R',0};
  U8 StrPBR[]={'P','B','R',0};
  U8 StrPBMR[]={'P','B','M','R',0};
  U8 StrABHR[]={'A','B','H','R',0};
  U8 StrABLR[]={'A','B','L','R',0};
  U8 StrDBR[]={'D','B','R',0};
  U8 StrDBMR[]={'D','B','M','R',0};
  U8 *NameAry[]={StrSP,StrSR,StrPC,StrVBR,
                 StrCSR,StrAABR,StrTDR,StrPBR,StrPBMR,
                 StrABHR,StrABLR,StrDBR,StrDBMR,0};
  U16 NumAry[]={REG_SP,REG_SR,REG_PC,REG_VBR,
                REG_CSR,REG_AABR,REG_TDR,REG_PBR,REG_PBMR,
                REG_ABHR,REG_ABLR,REG_DBR,REG_DBMR};
  int i;
  for(i=0;NameAry[i];i++)
    if(strcmp(RegName,NameAry[i])==0)
      return NumAry[i];
  if(*RegName=='A')
    if(('0'<=RegName[1])&&(RegName[1]<='6'))
      return REG_A0-RegName[1]+'0';
  if(*RegName=='D')
    if(('0'<=RegName[1])&&(RegName[1]<='7'))
      return REG_D0-RegName[1]+'0';
  return 0xffff;
}

void EditReg(U8 *RegName)
{ U8 buff[4],*Str;
  U16 RegNum;
  if((RegNum=GetRegNum(RegName))==0xffff)
  { TransmitByte('E');
    TransmitByte('r');
    TransmitByte('r');
    TransmitByte('R');
    TransmitByte('e');
    TransmitByte('g');
    TransmitByte(7);
    TransmitByte(13);
    TransmitByte(10); }
  else
  { ReadReg(RegNum,(U32*)buff);
    HexLongStr(0,buff);
    TransmitByte(' ');
    TransmitByte('-');
    TransmitByte('>');
    TransmitByte(' ');
    if((Str=GetStr(1))==0)
      return;
    if(hex2bin(Str,buff+3)||hex2bin(Str+2,buff+2)||
       hex2bin(Str+4,buff+1)||hex2bin(Str+6,buff))
      SendHexErr();
    else
      WriteReg(RegNum,*(U32*)buff);
  }
}

void ECHO(void)
{ int i;
  U8 c;
  for(;;)
  {
    SetDmaCount(4);
    for(i=0;i<4;i++)
    {
      c=ReceiveByte();
      if(timeOut)
        break;
      else
        TransmitByte(c);
    }
  }
}

void HEXCH(void)
{ int i;
  U8 c;
  for(;;)
  {
    SetDmaCount(4);
    for(i=0;i<4;i++)
    {
      c=ReceiveByte();
      if(timeOut)
        break;
      else
      {
        TransmitByte(' ');
        TransmitByte(bin2hex[15&(c>>4)]);
        TransmitByte(bin2hex[c&15]);
      }
      if(c==3)
      {
        SetWatchDog(3);
        for(timeOut=0;timeOut==0;);
        return;
      }
    }
  }
}

void TestCmp(U16 f)
{ U32 a1,a2;
  U16 l;
  U8 *s;
  TransmitByte('A');
  TransmitByte('1');
  TransmitByte(':');
  if((s=GetStr(1))==0)
    return;
  if(hex2long(s,(U8*)&a1))
  { SendHexErr();
    return; }
  TransmitByte('A');
  TransmitByte('2');
  TransmitByte(':');
  if((s=GetStr(1))==0)
    return;
  if(hex2long(s,(U8*)&a2))
  { SendHexErr();
    return; }
  TransmitByte('L');
  TransmitByte('e');
  TransmitByte('n');
  TransmitByte(':');
  if((s=GetStr(1))==0)
    return;
  if(hex2word(s,(U8*)&l))
  { SendHexErr();
    return; }
  s[0]=CompareMem(a1,0,l,a2,0,f);
  HexByteStr(0,s);
  HexLongStr(' ',BDMTempB);
  HexWordStr(' ',BDMTempB+4);
  HexWordStr(' ',BDMTempB+6);
  HexLongStr(' ',BDMTempB+8);
  HexWordStr(' ',BDMTempB+12);
  HexWordStr(' ',BDMTempB+14);
  TransmitByte(13);
  TransmitByte(10);
}

void TestCpy(U16 f)
{ U32 a1,a2;
  U16 l;
  U8 *s;
  for(;;)
  {
    TransmitByte('A');
    TransmitByte('1');
    TransmitByte(':');
    if((s=GetStr(1))==0)
      return;
    if(hex2long(s,(U8*)&a1))
      SendHexErr();
    else
      break;
  }
  for(;;)
  {
    TransmitByte('A');
    TransmitByte('2');
    TransmitByte(':');
    if((s=GetStr(1))==0)
      return;
    if(hex2long(s,(U8*)&a2))
      SendHexErr();
    else
      break;
  }
  for(;;)
  {
    TransmitByte('L');
    TransmitByte('e');
    TransmitByte('n');
    TransmitByte(':');
    if((s=GetStr(1))==0)
      return;
    if(hex2word(s,(U8*)&l))
      SendHexErr();
    else
      break;
  }
  if(f)
    s[0]=PostCopyMem(a1,0,l,a2,0,1);
  else
    s[0]=PreCopyMem(a1,0,l,a2,0,1);
  HexByteStr(0,s);
  HexLongStr(' ',BDMTempB);
  HexWordStr(' ',BDMTempB+4);
  HexWordStr(' ',BDMTempB+6);
  HexLongStr(' ',BDMTempB+8);
  HexWordStr(' ',BDMTempB+12);
  HexWordStr(' ',BDMTempB+14);
  TransmitByte(13);
  TransmitByte(10);
}

void TestSearch()
{ U32 a;
  U16 l1,l2;
  U8 Buf[128];
  U8 *s;
  TransmitByte('S');
  TransmitByte('t');
  TransmitByte('r');
  TransmitByte('i');
  TransmitByte('n');
  TransmitByte('g');
  TransmitByte(':');
  TransmitByte(' ');
  if((s=GetStr(0))==0)
    return;
  for(l2=0;s[l2];l2++)
    Buf[l2]=s[l2];
  if(l2==0)
    return;
  TransmitByte('A');
  TransmitByte('d');
  TransmitByte('d');
  TransmitByte('r');
  TransmitByte(':');
  if((s=GetStr(1))==0)
    return;
  if(hex2long(s,(U8*)&a))
  { SendHexErr();
    return; }
  TransmitByte('L');
  TransmitByte('e');
  TransmitByte('n');
  TransmitByte(':');
  if((s=GetStr(1))==0)
    return;
  if(hex2word(s,(U8*)&l1))
  { SendHexErr();
    return; }
  s[0]=SearchMem(a,0,l1,l2,Buf);
  HexByteStr(0,s);
  HexLongStr(' ',BDMTempB);
  TransmitByte(13);
  TransmitByte(10);
}
