Радио-86РК/Радио 07-90/Обработка файлов на компьютерах IBM/Листинг 2
| Данный материал защищён авторскими правами!
Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей. Автор: Ю. ЛЕСНЫХ Источник: 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);
}