Радио-86РК/Радио 07-90/Обработка файлов на компьютерах IBM/Листинг 1
| Данный материал защищён авторскими правами!
Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей. Автор: А. ДОЛГИЙ |
program RK86;
type STR2 = string[2]; STR4 = string[4]; TXT = text;
FILE_OF_BYTE = file of byte;
const KEYBAS1: STR4 = #$D3#$D3#$D3#$D3;
KEYBAS2: STB4 = #$D3#$D3#$D3#$00;
KEYED: STB4 = #$e6#$E6#$E6#$E6;
var R: file; S: FILE_OF_BYTE; T: TXT;
RNAME, SNAME, TNAME: string[14];
OPTION: array[1..10] of string[40];
LINE: string[72]; KEY; STR4;
BUF: аrrаy[1..128] of char;
I, J, RD: integer; B: byte; FINAL: boolean;
function HEXCHAR(B: byte): char;
var B1: byte;
begin
B1:= (B and $F) or $30; If В1 > $39 then B1:= B1 + $7;
HEXCHAR:= CHR(B1);
end;
function HEXBYTE(B: byte): STR2;
begin
HEXBYTE:= HEXCHAR(B shr 4) + HEXCHAR(B)
end;
function HEXINT(I: integer): STR4;
begin
HEXINT:= HEXBYTE(HI(I)) + HEXBYTE(LO(I))
end;
function RDINT(var F: FILE_OF_BYTE): integer;
var H, L: byte;
begin
READ(F,L); READ(F,H); RDINT:= L + H shl 8
end;
function LESS(I, J: integer): boolean;
begin
LESS:= (HI(I) < HI(J)) or ((HI(I) = HI(J)) and (LO(I) < LO(J)))
end;
function TRAHSRUS(B: byte): char;
const RUS: array[1..31] of char =
'ЮАБЦДЕФГХИИКЛМНОПЯРСТУЖСВЬЫЗШЭШЧ';
begin
If В in ($60..$7E) then TRANSRUS:= RUS(B - $5F)
else TRAHSRUS:= CHR(B);
end;
function OPTSEL(NOPT: byte): byte;
const DOTLINE: string (40) =
'-------------------------------------------------------------';
var I,N: byte; c: char;
begin
WRITELN(DOTLINE);
for I:= 1 to NOPT do WRITELN(I: 2.' - ',OPTION(I));
WRITELN(DOTLINE); WRITE(' ? ' );
repeat
READ(KBD,C);N:= ORD(C) - $30;
until N in (1..NOPT);
WRITELN(C); OPTSEL:= N;
end;
procedure NAMETEXT;
begin
WRITE('B КАКОЙ ФАЙЛ ЗАПИСАТЬ ? '); READLN(TNAME);
ASSIGN(T, TNAME); REWRITE(T) ;
end;
procedure BASIC_MICRON;
var CSUM, CSUMR, NOPT, I, ADR, N, ERRCNT, LINEСNТ,
LINENR: integer; WNAME: string(14); E, W: TXT; B: byte;
FINISH, EXIT: boolean;
procedure KEYWORD(var F: TXT;B: byte);
const TOKEN: array[0..91] of string(8) = (
'CLS', 'FOR', 'NEXT', 'DATA', 'INPUT', 'DIM', 'READ',
'CUR', 'GOTO', 'RUN', 'IF', 'RESTORE', 'GOSUB','RETURN',
'REN', 'STOP', 'OUT', 'ON', 'PLOT', 'LINE', 'POKE',
'PRINT', 'OFF', 'CONT', 'LIST', 'CLEAR', 'CLOAD', 'CSAVE',
'NEW', 'TAB(', 'TO', 'SPC(', 'FN', 'THЕN', 'NOT', 'STEP',
'+','-','*','/',',','AND', 'OR', '>','=','<', 'SGN',
'INT', 'ABS', 'USR', 'FRE', 'INP', 'POS', 'SQR', 'RND',
'LOG', 'EXP', 'COS', 'SIN', 'ТАN', 'АТN', 'PEEK', 'LEN',
'STR*', 'VAL', 'ASC', 'CHR*', 'LEFT*', 'RIGHT*', 'MID*',
'SCREEN$(', 'INKEY*', 'AT', '&', 'BEEP', 'PAUSE',
'VERIFY', 'НОMЕ', 'EDIT', 'DELETE', 'MERGE', 'AUTO',
'HIMEM', '@', 'ASN', 'ADDR', 'PI', 'RENUM', 'ACS', 'LG',
'LPRINT', 'LLIST');
begin
WRITE(F,TOKEN(B - 128))
end;
procedure ERRMSG(ERNR: byte);
begin
If ERRCNT = 0 then begin
WRITELN(E); WRITELN(E,'ОШИБКИ И ПРЕДУПРЕЖДЕНИЯ:')
end;
WRITE(E,'СТРОКА', LINENR: 10.' : ');
саsе ERNR of
1,2: WRITE(E,HEXBYTE(B));
3..5: KEYWORD (E, В);
end;
саsе ERNR of
1: begin
WRITE(E,' - ПСЕВДОГРАФИЧЕСЕЙ КОД');
WRITELN(E, ' ЭАМЕНЕН НА Ш' )
end;
2: begin
WRITE(E, ' - ЗАПРЕШЕННЫЙ КОД' );
WRITELN(E, ' ЗАМЕНЕН НА #');
end;
3: begin
WRITE(E,' - В BASIC-80');
WRITELN(E,' HE РЕАЛИЗОВАН');
end;
4: begin
WRITE(E,' - В BASIC-80 РАБОТАЕТ ИНАЧЕ. ');
WRITELN(E,' ЧЕМ В BASIC MICRON')
end:
5: begin
WRITE(E, ' - ДИРЕКТИВА ОПЕРАТОРА');
WRITELN(E,' B ПРОГРАММЕ' );
end:
end;
ERRCNT:= ERRCNT + 1;
end;
begin
ОРТION[3]:= 'ЗАПИСАТЬ ТЕКСТ ПРОГРАММЫ';
OPTION[4]:= 'ЗАПИСАТЬ ОШИБКИ И ПРЕДУПРЕ1ДЕНИЯ';
WRITELN; WRITELN('BASIC*MICRON : ',LINE);
NOPT:= 3; EXIT:= false;
repeat
саsе OPTSEL (NOPT) of
1: begin EXIT:= true; FINAL:= true end;
2: begin EXIT:= true; FINAL:= false end;
3: begin
FINISH:= false; NAMETEXT;
RESET(S); repeat READ(S,B) until B = 0;
ASSIGN(E,'ERR.ORS'); REWRITE(E);
I:= 1; CSUM:= 0; LINECNT:= 0; ERRCNT:= 0;
repeat;
READ(S,B); CSUM:= CSUM + B;
case I of
1: ADR:= B;
2: begin
ADR:= ADR + B shl 8
if ADR 0 then FINISH true
end
3: LINENR:= B;
4: begin
LINENR:= LINENR + B shl 8;
case LINENR of
0..9: N:= 1;
10..99: N:= 2;
100..999: N:= 3;
1000..9999: N:= 4;
10000..32767: N:= 5;
end;
WRITE(T,LINENR N '); LINECNT:= LINECNT + 1;
end
else case B of
0: begin I:= 0; WRITELN(T); end
1,7,9,11,13,23,27,31: begin WRITE(T,'Ш'); ERRMSG(1); end
8,10,12,24,20,220,255: begin WRITE(T #'); ERRMSG(2); end
32,127: WRITE(T,TRANSRUS(B));
128,133,146,147,154,155,198,200,205,208,211,217: begin KEYWORD(T,B); ERRMSG(3); end
144,148,153,177,179,189,218: begin KEYWORD(T,B); ERRMSG(4); end
137,151,152,156,208,207,209,210,215,219: begin KEYWORD(T,B); ERRMSG(5); end
else KEYWORD(T,B)
end
end
I:= I + l;
until FINISH Or EOF(S);
WRITELN; WRITE('B ФАЙЛ ',TNAME,' ЗАПИСАНО');
WRITELN(LINECNT,' CTPOK');
WRITELN('НОМЕР ПОСЛЕДНЕЙ СТР0КИ ',LINENR);
if not FINISH then begin
WRITELN('КОНЕЦ ПРОГРАММЫ НЕ НАЙДЕН');
WRITELN(T);
end
if ERRCNT > 0 then begin
WRITELN(ERRCNT,' ошибок/предупреждении');
NOPT:= 4;
end else begin CLOSE(E); ERASE(E); NOPT:= 3; end
end
4: begin
RESET(E); WRITE('B КАКОЙ ФАЙЛ ЗАПИСАТЬ ?');
READLN(WNAME);
if WNAME = TNAME then while not EOF(E) do begin
READLN(E,LINE); WRITELN(T,LINE);
end else begin
ASSIGN(W,WNAME); REWRITE(W);
while not EOF(E) do begin
READLN(E,LINE); WRITELN(W,LINE);
end;
end
CLOSE(W); CLOSE(E); ERASE(E); NOPT:= 3;
end
end
CLOSE(T);
until EXIT
end
procedure ED_MICRON
var LEN: Integer; В: byte; EXIT: boolean;
begin
ОРТION[3]:= 'ЗАПИСАТЬ ТЕКСТ';
READ(S,В); LEN:= RDINT(S);
WRITELN; WRITELN('ЕD_MИКРОН',LINE);
WRITELN(LEN,' БАЙТ'); EXIT:= false;
repeat
саsе OPTSEL(3) of
1: begin EXIT:= true; FINAL:= true; end
2: begin EXIT:= true; FINAL:= False; end
3: begin
NAMETEXT:= SEEK(S,3); READ(S,B);
While (B <> $FF) and not EOF(S) do begin
WRITE(T,TRANSRUS(B));
If B = $0D then WRITE(T,#$0A); READ(S,B);
end
if B <> $FF then begin
WRITELN(T); WRITELN('HE НАЙДЕН КОНЕЦ ТЕКСТА'); end
CLOSE(T);
end
end
until EXIT;
end
procedure MONITOR
var ADR, BEGADR, EHDADR, CSUM, CSUMR, I, FI, LA, NOPT,
CT, CS, FSIZE, PS: integer; NADR, STR4, ВТ: string[3]
B: byte; CH, D: char; ER, EXIT: boolean;
procedure LSPAS,
var I,J: integer; FIN: boolean;
procedure KEYWORD(var F: TXT; B: byte)
const ТOKEN: array[1 31] of string(9) (
'FOR','TO','DO','IF','THEN','ELSE','BEGIN','END',
'OF', 'DIV','MOD','READ','WRITE','MEM','CALL',
'REPEAT','WHILE','UNTIL','OR','AND','NOT','CASE',
'CONST','VAR','FUNCTION','PROCEDURE','DOWNTO',
'INTEGER','ARRAY','SHL','SHR');
begin WRITE(F,TOKEN(B,128) end
begin
WRITELN; WRITE(' ПАСКАЛЬ LS '); SEEK(S,6); READ(S,B);
while B <> $0D do begin
WRITE(TRANSRUS(B)); READ(S,B);
end
WRITELN; NAMETEXT:= I + 1; FIN:= false; SEEK(S,15);
repeat
READ(S,B);
case I of
1: if B = 1 then FIN:= true;
2,3: else case B of
$05: WRITE(T,'(*');
$0D: begin WRITELN(T) I:= 0; end
$12: WRITE(T,'*)');
$20: If I <> 4 then WRITE(T,'.');
$21..$7E: WRITE(T,TRANSRUS(B));
$80..$9F: KEYWORD(T,B) ;
$FF: begin
READ(S,B);
for J:= 1 to B + 1 do WRITE(T,' ');
end
end
end
I:= I + 1;
until FIN;
CLOSE(T);
end
function CHECK(CT: integer): integer;
vаг SL,SH: integer; B: byte;
begin
SL:= 0; SH:= 0;
while CT <> 1 do begin
READ(S,B); SL:= SL + B; SH:= SH + B + HI(SL); SL:= SL and $FF;
CT:= CT + 1;
end
READ(S,B); SL:= (SL + B) and $FF;
CHECK:=SL + (LO(SH) shl 8);
end
begin
ОРТION[3]:= ' ЗАПИСАТЬ DUMP';
OPTION[4]:= ' ЗАПИСАТЬ HEX';
FSIZE:= FILESIZE(S); WRITELN;
BEGADR:= ORD(KEY[2]) + ORD(KEY[1]) shl 8;
ENDADR:= ORD(KEY[4]) + ORD(KEY[3]) shl 8;
If LESS(ENDADR,BEGADR) then begin
WRITELN(FSIZE,' БАИТ ТИП ФАЙЛА IE ОПРЕДЕЛЕН');
repeat
WRITE('ВВЕДИТЕ НАЧАЛЬНЫЙ АДРЕС (HEX)');
NADR:= 0000; READLN(NADR); BEGADR:= 0; ЕR:= false;
for I:= 1 to LENGTH(NADR) do begin
D:= NADR[I];
case D of
0..9: B: ORD(D) = $30;
A..F: B: ORD(D) = $37;
else ER true
end
BEGADR:= B + BEGADR shl 4;
end
ENDADR:= BEGADR + FSIZE;
ЕR:= ЕR or LESS(ENDADR,BEGADR);
if ЕR then WRITE(' ОШИВКА!');
until not ER
end else begin
WRITELN(' ФАЙЛ MOHUTOPA.');
If (FSIZE-4) < (ЕNDADR-BEGADR) then begin
WRITE(' Данных меньше чем задано адресами');
WRITELN(HEXINT(BEGADR),НЕХINT(ЕNDАDR));
ENDADR:= FSIZE + BEGADR - 4;
end
SEEK(S,4);
end
WRITELN('НАЧАЛО ->',HEXINT(BEGADR));
WRITELN('КОНЕЦ ->',HEXINT(ENDADR));
WRITE('КОНТР CYMMA ->'); PS:= FILEPOS(S);
CSUM:= CHECK(ENDADR,BEGADR); WRITE(HEXINT(CSUM));
B:= $0 while not (EOF(S) or (B $E6)) do READ(S,B);
If LESS(FILEPOS(S),FSIZE) then begin
CSUMR:= SWAP(RDINT(S));
if CSUM <> CSUMR Then begin
WRITELN(' ? ');
end else
WRITELN;
WRITELN(' ',HEXINT(CSUMR));
end else begin
WRITELN;
WRITE('В ИСХОДНЫХ ДАННЫХ КОНТРОЛЬНАЯ СУММА ');
WRITELN(' ОТСУТСТВУЕТ');
end;
repeat
SEEK(S,4);
if (BEGADR = $3003) and (RDINT(5) = ENDADR) then begin
NOPT:= 5;
OPTION[5]:= 'Обработать как ПАСКАЛЬ-ПРОГРАММУ';
end else NOPT:= 4;
SEEK(S,PS); EXIT:= false;
case OPTSEL(NOPT) of
1: begin EXIT:= true; FINAL:= true end;
2: begin EXIT:= tгue; FINAL:= false end;
3: begin
NAMETEXT; ADR:= BEGADR;
repeat
LINE:= HEXINT(ADR) + ' ';
FI:= АDR and $F; LA:= ENDADR - ADR;
If LA > $0F then LA:= $0F;
for I:= 0 to 15 do begin
if I in [FI..LA] then begin
READ(S,B); ADR:= ADR + 1; BT:= HEXBYTE(B) + ' ';
if B in [ $20..$7E] then CH:= TRANSRUS(B);
else CH:= '.';
end else begin BT:= ' '; CH:= ' ' end;
INSERT(BT,LINE,I*3+7); LINE:= LINE + CH;
end;
while LINE[LENGTH(LINE)] = ' ' do
DELETE(LINE,LENGTH(LINE),1);
WRITELN(T,LINE);
until LESS(ENDADR,ADR);
end;
4: begin
NAMETEXT; ADR:= BEGADR;
repeat
FI:= ADR and $0F; LA:= ENDADR - ADR;
If LA > $0F then LA:= $0F; CT:= LA - FI + 1;
LINE:= ':' + HEXBYTE(CT) + HEXINT(ADR) + '00';
CS:= CT + HI(ADR) + LO(ADR);
for I:= 1 to CT do begin
READ(S,B); ADR:= ADR + 1; LINE:= LINE + HEXBYTE(B);
CS:= CS + B;
end;
LINE:= LINE + HEXBYTE(LO(-CS)); WRITELN(T,LINE);
Until LESS(ENDADR,ADR);
WRITELN(T,':00000000');
end;
5: LSPAS;
end;
until EXIT;
CLOSE(T);
end;
begin
CLRSCR;
WRITELN('**ASD-88*************************************');
WRITELN('* *'); *');
WRITELN('* ОБРАБОТКА ФАЙЛОВ РАДИО-86РК *');
WRITELN('* *'); *');
WRITELN('*************************************VЗ. 1***');
FINAL:= false;
ОPTION[1]:= 'Закончить работу';
OPTION[2]:= 'Перейти к обработке другого файла':
repeat
WRITELN; WRITE('Какой файл обработать ?');
READLN(RNAME); ASSIGN(R,RNAME); RESET(R);
ASSIGN(S,'XXXXXXXX.XXX'); REWRITE(S);
BLOCKREAD(R,BUF,1,RD); KEY:= COPY(BUF,1,4);
J:= 1; LINE:= ' ';
If (KEY = KEYBAS1) or (KEY + KEYED) then begin
LINE:= COPY(BUF,5,POS(#00,BUF)-5);
repeat
BLOCREAD(R,BUF,1,RD); J:= POS(#$E6,BUF);
until J > 0;
end;
repeat
for I:= J to l28 do begin
B:= ORD(BUF(I)); WRITE(S,B);
end;
BLOCKREAD(R,BUF,1,RD); J:= 1;
until RD:= 0;
CLOSE(R);
RESET(S);
If (KEY = KEYBAS1) or (KEY = KEYBAS2) then BASIC_MICROH
else If KEY = KEYED then ED_MICRON else MONITOR;
until FINAL;
CLOSE(S); ERASE(S);
end.