Радио-86РК/Радио 07-90/Обработка файлов на компьютерах IBM/Листинг 2

Материал из Emuverse
Данный материал защищён авторскими правами!

Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей.

Автор: Ю. ЛЕСНЫХ

Источник: http://retro.h1.ru/RK86/RK_PC/RK86-PC.C

#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h> /* for mode definitions */
#include <io.h>
#include <stdio.h>
#include <string.h>

#define TRUE        0      /* Boolean constants */
#define FALSE       -1

int	l,I,J,RD,
        R,Ind,
	msim[17],
        Size = 512,
        Byt = 1,
	Final;
unsigned int  ErrCnt,LineCnt,LineNr;
unsigned char    Buf[512],
        TFmp[100000];
char	Rname[14],
        KeyBas1[4] = {0xd3,0xd3,0xd3,0xd3},
        KeyBas2[4] = {0xd3,0xd3,0xd3,0x00},
	KeyEd[4] = {0xe6,0xe6,0xe6,0xe6},
	Sname[14],
        Tname[14],
        Ename[14],
        CrLf[] = "\r\n",
        TransRus[] = "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧ",
        Hch[2],
        Hin[5],
        strk[5];
char    Key[4],
	Line[72],
	adrs[4];
FILE	*FilIn,
	*FilOut,
        *FLst,
        *FErr;
void endgo(void);
int simhex(char[]);

main()
{
    int k, kl, P1,Ch,Klen;
    Final = FALSE;
    fprintf(stdout,"\nПрограмма преобразования файлов RK86. v1.0\n");
    while (Final) {
        strcpy(Line,"Нет имени                                                               ");
        Size = 512;
        fprintf(stdout,"\nКакой файл обработать ?");
        gets(Rname);
        if (*Rname == 0) {
           Final = TRUE;
           continue;
        }
        R = open(Rname, O_RDONLY | O_BINARY);
        if (R < 0) {
           fprintf(stderr,"Ошибка открытия файла ->%s\n",Rname);
           continue;
        }
        Ind = 0; P1 = 0;
        clestr(Tname);
        clestr(Ename);
        Klen = strpos(Rname,'.',14);
        strncpy(Tname,Rname,Klen);
        strncpy(Ename,Rname,Klen);
        RD = read(R,Buf,Size);
        if ((Buf[0] == 0xe6) && (Buf[1] != 0xe6)) {
           P1 = 1;
        }
        else {
             if ((Buf[0] == 0xe6) && (Buf[4] == 0xe6)) {
                P1 = 1;
             }
        }
        if (RD == 0) {
           fprintf(stderr,"Буфер пуст !!!!!!\n");
           continue;
        }
        clestr(Key);
        strncpy(Key,Buf + P1,4);
        J = P1;
        if(strncmp(Key,KeyBas1,4) == NULL || strncmp(Key,KeyEd,4) == NULL) {
                clestr(Line);
                P1 = P1 + 4;
                kl = strpos(Buf,0x00,RD);
                strncpy(Line,Buf + P1,kl + 1);
                while ((J = strpos(Buf + P1,0xe6,RD - P1)) == 0) {
                        RD = read(R,Buf,Size);
                        if (RD == 0) {
                           fprintf(stdout,"Не найден синхробайт\n");
                           break;
                        }
                        P1 = 0;
                }
  /*              J = strpos(Buf,0xe6) + 1; */
                J = J + 1;
        }
        while (RD != NULL) {
              for (I = J; I < Size; I++) {
                  TFmp[Ind] = Buf[I];
                  Ind++;
              }
              RD = read(R,Buf,Size);
              if (RD < Size) Size = RD;
              J = 0;
        }
        close(R);
        clestr(Rname);
/*        strncpy(Key,TFmp,4);   */
        if (strncmp(Key,KeyBas2,3) == NULL) BasicMicron();
          else if (strncmp(Key,KeyEd,4) == NULL) EdMicron();
               else Monitor();
    }
    return;
}

BasicMicron()
{
static char *Token[] = {"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    B,
                 *ErrStr;
        unsigned int Csum,
                 Csumr,
                 Adr;
 /*                N;     */
        int   Finish,
              Pos = 4;
        fprintf(stdout,"Программа на Basic Micron имя файла -> %s\n",Line);
        Finish = FALSE;
        strcat(Tname,".bas");
        strcat(Ename,".err");
        fprintf(stdout,"Программа записывается в файл %s\n",Tname);
        FLst = fopen(Tname,"wb");
        if (FLst == 0) {
           fprintf(stderr,"Ошибка открытия файла %s \n",Tname);
        }
/*        B = TFmp[Pos]; Pos++;    */
        FErr = fopen(Ename,"wb");
        if (FErr == 0) {
           fprintf(stderr,"Ошибка открытия файла %s \n",Ename);
        }
        Csum = 0;
        LineCnt = 0;
        Adr = 0;
        ErrCnt = 0;
        while (Finish) {
              RD = FALSE;
              B = TFmp[Pos];
              Pos++;
              Csum = Csum + B;
              Adr = B;
              B = TFmp[Pos];
              Pos++;
              Csum = Csum + B;
              Adr = Adr + (B * 256);
              if (Adr == 0) {
                 B = TFmp[Pos]; Pos++;
                 Csumr = B + (TFmp[Pos] << 8);
                 Pos++;
                 Finish = TRUE;
                 continue; /* I = 0; */
              }
              B = TFmp[Pos]; Pos++;
              Csum = Csum + B;
              LineNr = B;
              B = TFmp[Pos];
              Pos++;
              Csum = Csum + B;
              LineNr = LineNr + (B * 256);
              fprintf(FLst,"%4d ",LineNr);
              LineCnt++;
              while (RD) {
                    B = TFmp[Pos];
                    Pos++;
                    Csum = Csum + B;
                    if(B == 0) {
                         RD = TRUE;
                         fprintf(FLst,"%s",CrLf);
                         if (Pos > Ind) {
                            Pos = Ind - 5;
                         }
                         continue;
                    }
                    if(B != 0x00 && B < 0x20) {
                         HexByte(B);
                         ErrMSG(2,Hch);
                         continue; /*break;    */
                    }
                    if(B >= 0x20 && B < 0x80) {
                         if (B >= 0x60) {
                            fprintf(FLst,"%c",TransRus[B-0x60]);
                            continue; /* break; */
                         }
                         else {
                              fprintf(FLst,"%c",B & 0x7f);
                              continue;  /*break;  */
                         }
                    }
                    if (B >= 0xdc) {
                       fprintf(FLst,"%s","#");
                       HexByte(B);
                       ErrMSG(2,Hch);
                       continue; /*break; */
                    }
                    switch (B) {
                      case 128:
                      case 135:
                      case 146:
                      case 147:
                      case 154:
                      case 155:
                      case 198:
                      case 200:
                      case 205:
                      case 208:
                      case 211:
                      case 217:
                           fprintf(FLst,"%s",Token[B&0x7f]);
                           ErrMSG(3,Token[B&0x7f]);
                           break;
                      case 144:
                      case 148:
                      case 153:
                      case 177:
                      case 179:
                      case 189:
                      case 218:
                           fprintf(FLst,"%s",Token[B&0x7f]);
                           ErrMSG(4,Token[B&0x7f]);
                           break;
                      case 137:
                      case 151:
                      case 152:
                      case 156:
                      case 206:
                      case 207:
                      case 209:
                      case 210:
                      case 215:
                      case 219:
                           fprintf(FLst,"%s",Token[B&0x7f]);
                           ErrMSG(5,Token[B&0x7f]);
                           break;
                      default:
                           fprintf(FLst,"%s",Token[B & 0x7f]);
                           break;
                    }
              }/*      break;        */
   /*           }
              I++;    */
        }
        fprintf(stdout,"В файл %s записано %d строк\n",Tname,LineCnt);
        fprintf(stdout,"Номер последней строки %4d \n",LineNr);
        if (Finish != 0) {
           fprintf(stdout,"Конец у программы не найден \n");
           fprintf(FLst,"%s",CrLf);
        }
        fclose(FLst);
        if (ErrCnt > 0) {
           fprintf(stdout," %3d ошибок и предупреждений\n",ErrCnt);
           fprintf(stdout,"Ошибки записаны в файл ->%s\n",Ename);
           fclose(FErr);
        }
        else {
             fclose(FErr);
             remove(Ename);
        }
        fprintf(stdout,"Контрольная сумма -> %4X \n",Csum & 0xffff);
        if ((Csum & 0xffff) != Csumr) {
           if (Csumr == 0) {
              fprintf(stdout,"Контрольная сумма не задана\n");
           }
           else {
                fprintf(stdout,"Ошибка контрольной суммы ****************\n");
                fprintf(stdout,"Прочитанная %4X разность ->%4X\n",Csumr,Csumr - Csum & 0xffff);
           }
        }
        return;
}

int     strpos(char *Str,char S,int Lpos)
{       int Nps,Ik;
        Nps = 0;
        for (Ik = 0; Ik <= Lpos; Ik++ ) {
            if(S == Str[Ik]) {
                 Nps = Ik;
                 break;
            }
        }
        return(Nps);
}

int   clestr(char *Str)
{       int Ppos,Il;
        Ppos = strlen(Str);
        for (Il = 0; Il <= Ppos; Il++) {
            Str[Il] = 0x00;
        }
        return;
}

int    HexByte(char Cs)
{
static  char Mhex[] = "0123456789ABCDEF";
        int  Hb,Lb;
        Lb = Cs & 0x0f;
        Hb = (Cs >> 4) & 0x0f;
        Hch[0] = Mhex[Hb];
        Hch[1] = Mhex[Lb];
        Hch[2] = 0x00;
        return;
}

ErrMSG(TT,Bc)
int        TT;
char       *Bc;
{
        if (ErrCnt == 0) {
           fprintf(FErr,"\t Ошибки и предупреждения :\n");
        }
        fprintf(FErr,"Строка %4d ",LineNr);
        switch(TT) {
            case 1:
                 fprintf(FErr,"%s - псевдографический код, заменен на Ш\n",Bc);
                 break;
            case 2:
                 fprintf(FErr,"%s - Непечатный символ, заменен на # \n",Bc);
                 break;
            case 3:
                 fprintf(FErr,"%s - в Basic-80 не реализован\n",Bc);
                 break;
            case 4:
                 fprintf(FErr,"%s - в Basic-80 работает иначе чем в Basic Micron\n",Bc);
                 break;
            case 5:
                 fprintf(FErr,"%s - директива оператора в программе\n",Bc);
                 break;
        }
        ErrCnt++;
        return;
}

EdMicron()
{
        unsigned int    Csum,Csumr;
        int     Len,Exit,
                Pos = 0;
        unsigned char   B;
        Csum = 0;
        B = TFmp[Pos]; Pos++;
        Len = B + (TFmp[Pos] << 8);
        Pos++; Len = 0 - Len;
        fprintf(stdout,"Файл редактора MICRON имя файла ->%s\n",Line);
        fprintf(stdout,"Длина файла -> %4d  Байт\n",Len&0xffff);
        Exit = FALSE;
        strcat(Tname,".asm");
        fprintf(stdout,"Программа записывается в файл %s\n",Tname);
        FLst = fopen(Tname,"wb");
        if (FLst == 0) {
           fprintf(stderr,"Ошибка открытия файла %s \n",Tname);
        }
        while(Exit) {
             RD = Ind - Pos;
             while (B != 0xff && RD != 0) {
                   B = TFmp[Pos]; Pos++;
                   Csum = Csum + B;
                   RD = Ind - Pos;
                   if (B == 0xff) {
                      Csum = Csum - B;
                      B = TFmp[Pos]; Pos++;
                      RD--;
                      Csumr = B + (TFmp[Pos] << 8);
                      RD--;
                      B = 0xff;
                      fprintf(stdout,"Контрольная сумма ->%4X \n",Csum & 0xffff);
                      if (Csumr != (Csum & 0xffff)) {
                         fprintf(stdout,"Ошибка контрольной суммы или она не задана\n");
                         fprintf(stdout,"Прочитана %4X  разность -> %4X\n",Csumr,Csumr - Csum & 0xffff);
                      }
                      Exit = TRUE;
                      close(FLst);
                      clestr(Tname);
                      continue;
                   }
                   if(B != 0x00 && B < 0x20) {
                        if(B == 0x0d) {
                             fprintf(FLst,"%s",CrLf);
                             continue;
                        }
                        else {
                             HexByte(B);
                             ErrMSG(2,Hch);
                             continue;
                        }
                   }
                   if(B >= 0x20 && B < 0x80) {
                        if (B >= 0x60) {
                           fprintf(FLst,"%c",TransRus[B-0x60]);
                           continue;
                        }
                        else {
                             fprintf(FLst,"%c",B & 0x7f);
                             continue;
                        }
                   }
                   if (B != 0xff) {
                      fprintf(FLst,"%s",CrLf);
                      fprintf(stdout,"Не найден конец текста \n");
                      Exit =TRUE;
                      B = 0xff;
                   }
             }
        }
        return;
}

Monitor()
{
 unsigned int    Adr,BegAdr,EndAdr,Csum,
        Csumr;
 int    Fi,La,Ct,Cs,Fsize,Ps,Iu,Ip,
        Er,Pos = 0,
        Sh,Sl,Pps;
 char   NAdr[3],
        Str4[3],
        Bt[3],
        Ch, D;
 unsigned char  B;
 Sl = Sh = 0;
 RD = FALSE;
 Csum = Csumr = 0;
 Fsize = Ind - 3;
 B = TFmp[Pos]; Pos++;
 BegAdr = TFmp[Pos] + (B << 8);
/* Sl = TFmp[Pos];  */  Pos++;
 B = TFmp[Pos]; Pos++;
 EndAdr = TFmp[Pos] + (B << 8);
/* Sl = Sl + TFmp[Pos];  */   Pos++;
 BegAdr = BegAdr & 0xffff;
 EndAdr = EndAdr & 0xffff;
 Pps = Pos;
 if (EndAdr < BegAdr) {
    fprintf(stdout,"Размер -> %d байт, тип файла не определен \n",Fsize);
    while (! Er) {
          fprintf(stdout,"Введите начальный адрес (HEX)\n");
          gets(NAdr);
          BegAdr = 0;
          Er = FALSE;
          BegAdr = simhex(NAdr);
          EndAdr = BegAdr + Fsize;
          Er = Er || (EndAdr < BegAdr);
          if (Er) {
             fprintf(stdout,"Ошибка !!!\n");
          }
    }
 }
 else {
      fprintf(stdout,"Файл МОНИТОРА RK86\n");
      if ((Fsize - Pos) < (EndAdr - BegAdr)) {
         fprintf(stdout,"Данных меньше, чем задано адресами %4X  %4X \n",BegAdr,EndAdr);
         EndAdr = Fsize - BegAdr - Pos;
      }
      strcat(Tname,".hex");
      strcat(Ename,".dmp");
 }
 fprintf(stdout,"Начало    программы -> %4X\n",BegAdr);
 fprintf(stdout,"Окончание программы -> %4X\n",EndAdr);
 for (Iu = Pps; Iu < Ind - 3; Iu++) {
     B = TFmp[Iu];
     Sl = Sl + B;
/*     Sh = Sh + B + (Sl >> 8) & 0xff; */
     Sh = Sh + B;
     if (((Sh >> 8) & 0xff) > 0) Sh = Sh + 1;
     Sh = Sh & 0xff;
     Sl = Sl & 0xff;
 }
 Csum = Sl + ((Sh & 0xff) << 8);
 fprintf(stdout,"Контрольная суммма  -> %4X\n",Csum & 0xffff);
 B = TFmp[Ind - 2];
 Csumr = TFmp[Ind - 1] + (B << 8);
 if (Csumr != (Csum & 0xffff)) {
    fprintf(stdout,"Ошибка контрольной суммы или она отсутствует\n");
    fprintf(stdout,"\tСумма в файле -> %4X \n",Csumr);
    fprintf(stdout,"\tЦиклическая сумма -> %2X\n",Sh);
    fprintf(stdout,"\t            Сумма -> %2X\n",Sl);
    fprintf(stdout,"\t         Разность -> %2X\n",B - Sh);
    fprintf(stdout,"\t         Разность -> %2X\n",Sh - B);
    fprintf(stdout,"\t         Инверсия -> %2X\n",0 - Sh);
    fprintf(stdout,"\t         Инверсия -> %2X\n",0 - B);
 }
 fprintf(stdout,"Dump записывается в файл %s\n",Ename);
 FErr = fopen(Ename,"wb");
 if (FErr == 0) {
    fprintf(stderr,"Ошибка открытия файла %s \n",Ename);
 }
 Adr = BegAdr;
 clestr(Line);
 strcat(Line,"*");
 while(RD) {
     HexInt(Adr);
     fprintf(FErr,"%s   ",Hin);
     Fi = Adr & 0x0f;
     La = EndAdr - Adr;
     if (La > 0x0f) {
        La = 0x0f;
     }
     else if (La < 0) La = 0;
     for (Iu = 0; Iu <= La; Iu++) {
         B = TFmp[Pos]; Pos++;
         HexByte(B);
         fprintf(FErr,"%s ",Hch);
         Adr++;
         if(B >= 0x20 && B < 0x80) {
              if (B >= 0x60) {
                 Bt[0] = TransRus[B-0x60];
                 Bt[1] = 0x00;
                 strcat(Line,Bt);
              }
              else {
                   Bt[0] = B;
                   Bt[1] = 0x00;
                   strcat(Line,Bt);
              }
         }
         else strcat(Line,".");
         if (Adr > EndAdr) {
            RD = TRUE;
            break;
         }
     }
     strcat(Line,"*");
     fprintf(FErr,"  %s\r\n",Line);
     clestr(Line);
     strcat(Line,"*");
 }
 close(FErr);
 clestr(Ename);
 RD = FALSE;
 Pos = Pps;
 fprintf(stdout,"Программа в Intel формате в файле %s\n",Tname);
 FLst = fopen(Tname,"wb");
 if (FLst == 0) {
    fprintf(stderr,"Ошибка открытия файла %s \n",Tname);
 }
 Adr = BegAdr;
 while (RD) {
       Fi = Adr & 0x0f;
       La = EndAdr - Adr;
       if (La > 0x0f) {
          La = 0x0f;
       }
       Ct = La - Fi + 1;
       HexByte(Ct);
       fprintf(FLst,":%s",Hch);
       HexInt(Adr);
       fprintf(FLst,"%s00",Hin);
       Cs = Ct + Adr/256;
       Cs = Cs + (Adr - (Adr/256)*256);
       for (Iu = 1; Iu <= Ct; Iu++) {
           B = TFmp[Pos]; Pos++;
           Adr++;
           HexByte(B);
           fprintf(FLst,"%s",Hch);
           Cs = Cs + B;
           if (Adr > EndAdr) {
              RD = TRUE;
              break;
           }
       }
       Cs = 256 - (Cs & 0x00ff);
       HexByte(Cs);
       fprintf(FLst,"%s\r\n",Hch);
 }
 fprintf(FLst,":00000001FF\r\n");
 close(FLst);
 clestr(Tname);
 return;
}

int    HexInt(unsigned int Ad)
{
        int  Hb,Lb;
        Lb = Ad & 0x0ff;
        Hb = (Ad >> 8) & 0x0ff;
        HexByte(Hb);
        strcpy(Hin,Hch);
        HexByte(Lb);
        strcat(Hin,Hch);
        Hin[5] = 0x00;
        return;
}

int simhex(stnrk)
char	stnrk[];
{
static  char Mhex[] = "0123456789ABCDEF";
	unsigned int ch1;
	int	j,k[4],m;
    for (j = 0; j <= 3; j++) {
		k[j] = 0;
		ch1 = stnrk[j];
		if( ch1 > 0x5f) ch1 = ch1 & 0x5f;
		if(ch1 < 0x30 || ch1 > 0x46) {
			fprintf(stderr,"Неправильный байт -> |%c|%x|\n",ch1,ch1);
			ch1 = Correct(ch1);
		}
		for (m = 0; m < 16; m++) {
			if (Mhex[m] == ch1) {
				k[j] = m;
				break;
			}
		}
    }
    ch1 = (k[0] * 4096 + k[1] * 256 + k[2] * 16 + k[3]);
    return(ch1);
}

int 	Correct(ss)
int 	ss;
{
	switch(ss) {
		case 0x4f:
		case 0x51:
			fprintf(stderr,"Замена %c на 0\n",ss);
			ss = '0';
			break;
		case 0x49:
		case 0x4c:
			fprintf(stderr,"Замена %c на 1\n",ss);
			ss = '1';
			break;
		case 0x5a:
			fprintf(stderr,"Замена %c на 2\n",ss);
			ss = '2';
			break;
		default:
			fprintf(stderr,"Замена %c на 0\n",ss);
			ss = '0';
			break;
	}
	return(ss);
}