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

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

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

Автор: А. ДОЛГИЙ

Источник: http://retro.h1.ru/RK86/RK_PC/ProgrammRK86.txt

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.