#include <stdio.h>
#include <bios.h>
#include <dos.h>
#include <dir.h>


#define len 45000U /* Max len of data array */


unsigned short const Port_Work=0x87;
unsigned short const Port_Out =0x85;
unsigned short const Port_Inp =0x86;
unsigned char const World=0x89; /* 10001001 */
short mode0,mode1;
char buf[len]; /* Buffer for data <- from APOGEY */
char *buf1,*buf2;
unsigned char Ver; /* To verify cancel */
FILE *fp;
short attrib;


void _line(void);
unsigned char inp_byte(unsigned char *Ver);
short power(short base,short n);
void _cancel(void);
unsigned char _new(unsigned char Bt);
void _pr(unsigned short J,unsigned short BC);


void main(void)
{
 unsigned char c; /* Dummy for key */
 unsigned char B,C;
 unsigned short BC;
 unsigned char K1,K2;
 unsigned short KC,KC1,KCX,KCB;

 unsigned char CC1,CC2;
 unsigned short CC;

 unsigned char N_E,N_EX;
 unsigned short L_B,L_BX;

 unsigned short PP1,PP2,PP3,PP4,PP5;

 unsigned char Bt;
 unsigned short J,Z;
 unsigned short I;
 char name_file[255];

 unsigned char VV;

 unsigned char const Ok=0x0A;
 struct ffblk buffer[255];

 char op[92][8]=
 {
  {"CLS"},{"FOR"},{"NEXT"},{"DATA"},{"INPUT"},{"DIM"},{"READ"},{"CUR"},
  {"GOTO"},{"RUN"},{"IF"},{"RESTORE"},{"GOSUB"},{"RETURN"},{"REM"},{"STOP"},
  {"OUT"},{"ON"},{"PLOT"},{"LINE"},{"POKE"},{"PRINT"},{"DEF"},{"CONT"},
  {"LIST"},{"CLEAR"},{"CLOAD"},{"CSAVE"},{"NEW"},{"TAB("},{"TO"},{"SPC("},
  {"FN"},{"THEN"},{"NOT"},{"STEP"},{"+"},{"-"},{"*"},{"/"},{"^"},{"AND"},
  {"OR"},{">"},{"="},{"<"},{"SGN"},{"INT"},{"ABS"},{"USR"},{"FRE"},{"INP"},
  {"POS"},{"SQR"},{"RND"},{"LOG"},{"EXP"},{"COS"},{"SIN"},{"TAN"},{"ATN"},
  {"PEEK"},{"LEN"},{"STR$"},{"VAL"},{"ASC"},{"CHR$"},{"LEFT$"},{"RIGHT$"},
  {"MID$"},{"SCREEN$("},{"INKEY$"},{"AT"},{"&"},{"BEEP"},{"PAUSE"},
  {"VERIFY"},{"HOME"},{"EDIT"},{"DELETE"},{"MERGE"},{"AUTO"},{"HIMEM"},
  {"@"},{"ASN"},{"ADDR"},{"PI"},{"RENUM"},{"ACS"},{"LG"},{"LPRINT"},
  {"LLIST"}
 };

 unsigned char _zero_;
 unsigned char _rem_;
 unsigned char _ap_;
 unsigned short Adr;
 unsigned char a1;
 unsigned char a2;
 unsigned char D;


 printf(" (C) Fursin Program - Transfer from 'APOGEY' to 'POISK'\n");

menu0:
 mode0=0;_line();printf(" Choose mode0:\n");
 printf(" 1) Input to terminal\n");
 printf(" 2) Input to RAM and save\n");
 printf(" 3) Quit\n");
menu0_i:
 c=(bioskey(0)&0xFF);
 switch(c)
 {
  case '1':mode0=1;goto menu1;
  case '2':mode0=2;goto menu1;
  case '3':goto end;

  default:printf("\a");goto menu0_i;
 }

menu1:
 mode1=0;_line();printf(" Choose mode1:\n");
 printf(" 1) Input basic     code\n");
 printf(" 2) Input assembler text\n");
 printf(" 3) Input standard  text\n");
 printf(" 4) Menu0     		 \n");

menu1_i:
 c=(bioskey(0)&0xFF);
 switch(c)
 {
  case '1':mode1=1;goto menu2;
  case '2':mode1=2;goto menu2;
  case '3':mode1=3;goto menu2;
  case '4':goto menu0;

  default:printf("\a");goto menu1_i;
 }

menu2:
 _line();printf(" Press key to input ");
 c=(bioskey(0)&0xFF);if (c==0x27) goto menu1;

 ;printf("[Press Shift to cancel]\n");

 outportb(Port_Work,World);

/* Begin input */
 _line();printf(" Finding parameters\n");
/* 0xAA55 */
 CC1=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 CC2=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 CC=CC2*256+CC1;
 if (CC!=0xAA55)
  {
   printf("Code of input is not correct\n");
   _cancel();goto Inp_end;
  }
/* Len */
 C=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 B=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 BC=B*256+C;
/* Control Summary */
 K1=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 K2=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 KC=K2*256+K1;
/* Number of max error */
 N_E=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
/* Number of block len */
 CC1=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 CC2=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 L_B=CC2*256+CC1;

 _line();printf(" Parameters:\n");
 printf(" Len of program      : %X\n",BC);
 printf(" Control summary     : %X\n",KC);
 printf(" Number of max error : %X\n",N_E);
 printf(" Len of block        : %X\n",L_B);

/* Begin logic */

 _line();printf(" Transfering data. Wait, please!\n");

 printf(" Was inputed ");
 VV=0;KC1=0;J=BC;buf1=&buf[0];
ii1:
 L_BX=L_B;N_EX=N_E;

ii3:
 PP1=J;PP2=L_BX;buf2=buf1;KCX=0;
ii2:
 outportb(Port_Out,0);
 Bt=inp_byte(&Ver);KCX+=Bt;if (Ver==1) {_cancel();goto Inp_end;}
 --J;--L_BX;
 _pr(J,BC);
 if ((mode0==2)&&(mode1==3)) {*buf1=_new(Bt);}
 else if ((mode1==1)||(mode0==2)) {*buf1=Bt;}
 ++buf1;if ((J!=0)&(L_BX!=0)) goto ii2;
 J=PP1;L_BX=PP2;buf1=buf2;

 CC1=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 CC2=inp_byte(&Ver);if (Ver==1) {_cancel();goto Inp_end;}
 KCB=CC2*256+CC1;

 if (KCX==KCB) goto ii4;
 outportb(Port_Out,1);for (Z=0;Z<0x1000;++Z);
 if (N_EX==0xFF) goto ii3;
 if (N_EX==0) goto ii5;
 --N_EX;goto ii3;
ii5:
 printf("\n");_line();printf(" Error transfering! Transfer canceled!");
 _cancel();goto Inp_end;

ii4:
 KC1=KC1+KCX;
ii7:
 --J;--L_BX;++buf1;if (J==0) goto Inp_end;
 if (L_BX!=0) goto ii7;
 goto ii1;

Inp_end:
 VV=1;if (VV==1) _pr(J-1,BC);
 *buf1=0;printf("\n");_line();printf(" Transfer ended ");
 if (KC==KC1) printf("normaly");
 else printf("with error [KC_inp<>KC_my]");
 printf("\n");

 if ((mode0==1)&&(mode1==1)) goto _a_save;
 else if (mode0==1) goto menu0;

 _line();printf(" Will you save text (Y/N)\n");
 D=bioskey(0);if ((D=='N')||(D=='n')) goto menu0;

loop_find:
 _line();
 printf(" Input name of file [<-Save data]:");gets(name_file);
 if (findfirst(name_file,buffer,attrib)!=-1)
  {_line();printf(" File alredy exists or error in name!\n");goto loop_find;}

_a_save:
 if ((mode0==2)&&(mode1==3))
  {
   fp=fopen(name_file,"wb");fwrite(&buf[0],1,BC,fp);fclose(fp);
  }

 else if ((mode0==2)&&(mode1==2))
  {
   _line();printf(" Translating and saving text\n");
   buf1=&buf[0];
   fp=fopen(name_file,"wb");
   for (J=1;J<=BC;++J)
    {
     Bt=*buf1;fwrite(buf1,1,1,fp);++buf1;
     if (Bt==0x0D) fwrite(&Ok,1,1,fp);
    }
   fclose(fp);
  }

 else if (mode1==1)
  {
   if (mode0==2) fp=fopen(name_file,"wt");
   _zero_=0;_rem_=0;_ap_=0;Adr=0;
   _line();
   if (mode0==2) printf(" Translating and saving text\n");
   else printf(" Translating and printing text\n");

   buf1=&buf[0];J=1;Ver=0;
   while (J<=BC)
    {
     Bt=*buf1;
     if (_zero_==1)
      {
       _zero_=0;++buf1;++J;
        if((*buf1)==0) break;
        else
         {
	  ++buf1;a1=*buf1;++buf1;a2=*buf1;Adr=a2*256+a1;J+=2;
	  if (mode0==2) fprintf(fp,"%u ",Adr);
	  else printf("%u ",Adr);
         }
      }
     else if (_rem_==1)
      {
       _rem_=0;
       while(1!=0)
       {
	Bt=*buf1;if (Bt==0) break;
	if (mode0==2) fprintf(fp,"%c",_new(Bt));
	else printf("%c",_new(Bt));
	++J;++buf1;
       }
       buf1-=1;J-=1;
      }
     else if(_ap_==1)
      {
       _ap_=0;
       while(Bt!=0x22)
       {
        Bt=*buf1;
	if (mode0==2) fprintf(fp,"%c",_new(Bt));
        else printf("%c",_new(Bt));
        ++J;++buf1;
       }
       buf1-=1;J-=1;
      }

     else if (Bt==0)
      {
       if (mode0==2) fprintf(fp,"\n"); else printf("\n");
       _zero_=1;_rem_=0;_ap_=0;Adr=0;
      }
     else if (Bt==0x22)
      {
       _ap_=1;
       if (mode0==2) fprintf(fp,"\"");
       else printf("\"");
      }
     else if (Bt>=0x80)
      {
       for (I=0;I<=8;++I)
	{
	 if (op[Bt-0x80][I]==0) break;
         if (mode0==2) fprintf(fp,"%c",op[Bt-0x80][I]);
	 else printf("%c",op[Bt-0x80][I]);
	}
       if (Bt==0x8E) {_rem_=1;}
      }
     else
      {
       if (mode0==2) fprintf(fp,"%c",_new(Bt));
       else printf("%c",_new(Bt));
      }

     ++J;++buf1;
     if ((peekb(0,1047) & 0x03)!=0) {Ver=1;break;}
    }
   if (Ver==0)
    {
     if (mode0==2) fprintf(fp,"\n");
     else printf("\n");
     if (mode0==2) fclose(fp);
    }
   else
    {
     if (mode0==2) fprintf(fp,"\n Transfer canceled\n");
     else _cancel();
     if (mode0==2) fclose(fp);
    }
  }

Save_end:
 goto menu0;

end:
 _line();printf(" End\n");
}

void _cancel(void)
{
 printf("\n");_line();printf(" Input canceled\n");
}

void _line(void)
{
 short i;

 printf(" ");
 for (i=1;i<=78;i++) {printf("Ä");} printf("\n");
}

unsigned char inp_byte(unsigned char *Ver)
{
 unsigned char B=0; /* Input byte */
 unsigned char I;   /* loop[base] */
 unsigned char V,V1,VV;/* Input bits */

 *Ver=0;

 for (I=0;I<=7;++I)
 {
  outportb(Port_Out,0);
x_loop:
  if ((peekb(0,1047) & 0x03)!=0) {*Ver=1;break;}
   V=inportb(Port_Inp);if ((V & 0x80)==0) goto x_loop;
   outportb(Port_Out,1);
    if ((V & 0x20)==0) V1=0; else V1=1;
  B=B+V1*power(2,I);
 }

 outportb(Port_Out,0);
 return B;
}

short power(short base,short n)
{
 short i,p;

 p=1;for (i=1;i<=n;++i) p=p*base;
 return p;
}

unsigned char _new(unsigned char Bt)
{
 unsigned char P;

 P=0xFF;

 if      (Bt==0x00) P=0x00;
 else if (Bt==0x03) P=0xDF;
 else if (Bt==0x06) P=0xDE;
 else if (Bt==0x0A) P=0x0A;
 else if (Bt==0x0B) P=0xF9;
 else if (Bt==0x0D) P=0x0D;
 else if (Bt==0x0E) P=0xF6;
 else if (Bt==0x0F) P=0xF8;
 else if (Bt==0x11) P=0xFD;
 else if (Bt==0x14) P=0xDC;
 else if (Bt==0x17) P=0xDB;
 else if (Bt==0x1A) P=0x2B;
 else if (Bt==0x1B) P=0xB3;
 else if (Bt==0x1C) P=0xC4;
 else if (Bt==0x1D) P=0xF7;
 else if (Bt==0x1F) P=0xB3;
 else if ((Bt>=0x20)&&(Bt<=0x5F)) P=Bt;

 else if (Bt==0x60) P=0x9E;
 else if (Bt==0x61) P=0x80;
 else if (Bt==0x62) P=0x81;
 else if (Bt==0x63) P=0x96;
 else if (Bt==0x64) P=0x84;
 else if (Bt==0x65) P=0x85;
 else if (Bt==0x66) P=0x94;
 else if (Bt==0x67) P=0x83;
 else if (Bt==0x68) P=0x95;
 else if (Bt==0x69) P=0x88;
 else if (Bt==0x6A) P=0x89;
 else if (Bt==0x6B) P=0x8A;
 else if (Bt==0x6C) P=0x8B;
 else if (Bt==0x6D) P=0x8C;
 else if (Bt==0x6E) P=0x8D;
 else if (Bt==0x6F) P=0x8E;
 else if (Bt==0x70) P=0x8F;
 else if (Bt==0x71) P=0x9F;
 else if (Bt==0x72) P=0x90;
 else if (Bt==0x73) P=0x91;
 else if (Bt==0x74) P=0x92;
 else if (Bt==0x75) P=0x93;
 else if (Bt==0x76) P=0x86;
 else if (Bt==0x77) P=0x82;
 else if (Bt==0x78) P=0x9C;
 else if (Bt==0x79) P=0x9B;
 else if (Bt==0x7A) P=0x87;
 else if (Bt==0x7B) P=0x98;
 else if (Bt==0x7C) P=0x9D;
 else if (Bt==0x7D) P=0x99;
 else if (Bt==0x7E) P=0x97;
 else if (Bt==0x7F) P=0xB1;

 if (P==0xFF) P=0xCE;

 return (P);
}

void _pr(unsigned short J,unsigned short BC)
{
 unsigned long J1;
 unsigned long J2;
 unsigned long JJ;
 if ((BC-J==BC)||(J%100)==0)
  {
   J1=BC-J;J2=BC;JJ=(J1*100)/J2;
   printf("    \b\b\b\b%3u\%\b\b\b\b",JJ);
  }
}
