Такая вот проблема. Есть ряд программ написанных на седьмом паскале, программки используют прерывание ком-порта. работали на машинах типа 300 мГц или 600 мГц под 98 виндой. а вот на новых машинах (?), ну более скоростных, не хотят работать, просто вообще не выполняется прерывание... вроде. Я сначала думал что это из-за того что 2000 винда, но нет, я поставил 98 на такую машину и все равно не работает. Помогите разобраться… потому что очень надо заставить эти программки работать на новых машинах… заранее благодарен.
___ALex___
5.08.2003 18:05
видимо архитектурные нововведения...
Что ты имеешь в виду под новыми машинами?? Напиши конфиг.
И попробуй запустить под голым ДОС'ом. И еще может проги хреновые?? ;)
>Что ты имеешь в виду под новыми машинами?? Напиши конфиг.
около гигаГерцовые машины.
>И попробуй запустить под голым ДОС'ом.
пробывал, не работает...
>И еще может проги хреновые??
может и хреновые, вопрос в том, почему же они на старых машинах работают...
А ты не пробовал скачать новый модуль CRT для работы на быстрых машинах ????
Вот-вот... какую ошибку может генерит?? Типа Runtime Error 200?
И приведи текст проги тада что-ли..
И что ты вкладываешь в понятие прерывания ком-порта??
Мож у тя там ишшо и код самодифицирующийся?
>Вот-вот... какую ошибку может генерит?? Типа Runtime Error 200?
не генерит никаких ошибок, программа функционирует, но приема-передачи по ком-порту нету...
>И приведи текст проги тада что-ли..
хорошо...
>И что ты вкладываешь в понятие прерывания ком-порта??
ну я в прерывании например прописываю чтобы символ выводился... а он не выводится, то есть прерывание должно сработать, но не срабатывает....
>Мож у тя там ишшо и код самодифицирующийся?
обьясни что это, я не понимаю....
crt пропатченный я вроде не использовал, вернее отдельно я не помню чтобы паскаль патчил, но есть подозрение что он у меня изначально пропатченный, потому что рантайм ерроров никаких не выдает, при компилировании на новых машинах... подскажите где взять этот патч, я его скачаю поставлю... вдруг... все зароботает...
итак текст программы, он большой... но раз попросили...
{Работа с ком-портами
Ком -1 }
type Yes_No =(Yes,No);
var
isr_old_COM1 : pointer; {вектор СomPort}
Base_addrCOM1_ : word; {Базовый адрес }
& nbsp;Base_addrCOM1_1,Base_addrCOM1_2,Base_addrCOM1_3,Base_addrCOM1_4,Base_addrCO
M1_5 :word;
PBA_COM1_1,PBA_COM1_2,PBA_COM1_3,PBA_COM1_4,PBA_COM1_5:byte;
function Ident_intCOM1_pr: boolean;
begin
if Port[Base_addrCOM1_2] and 4 = 4 then
Ident_intCOM1_pr:=true
else Ident_intCOM1_pr:=false;
end;
function Ident_intCOM1_per: boolean;
begin
if Port[Base_addrCOM1_2] and 2 = 2 then
Ident_intCOM1_per:=true
else Ident_intCOM1_per:=false;
end;
procedure RasreshCOM1_pr(rasr_pr:Yes_No);
begin
case rasr_pr of
Yes : Port[Base_addrCOM1_1]:=Port[Base_addrCOM1_1] or 1;
No : Port[Base_addrCOM1_1]:=Port[Base_addrCOM1_1] and not 1;
end;
end;
Procedure RasreshCOM1_per(rasr_per:Yes_No);
begin
case rasr_per of
Yes : Port[Base_addrCOM1_1]:=Port[Base_addrCOM1_1] or 2;
No : Port[Base_addrCOM1_1]:=Port[Base_addrCOM1_1] and not 2;
end;
end;
{!!!}
Procedure Wr_byteCOM1(dat:byte);
begin
Port[Base_addrCOM1_]:=dat;
end;
Procedure Rd_byteCOM1(var dat,AddrBit:byte);
begin
dat:=Port[Base_addrCOM1_];
if (Port[Base_addrCOM1_5] and 4)=4 then AddrBit:= 1 else AddrBit:=0;
end;
Procedure UstanAddrBitCOM1(bit:byte);
{Устанавливает бит четности в 0 или в 1 независимо от самой
четности}
begin
if bit=0 then Port[Base_addrCOM1_3]:= Port[Base_addrCOM1_3] or $38{Бит четности -> в 0}
else
begin
Port[Base_addrCOM1_3]:=Port[Base_addrCOM1_3] and not $38;
Port[Base_addrCOM1_3]:=Port[Base_addrCOM1_3] or $28;
end;
end;
{$f+}
procedure COM1_interrupt;
interrupt;
var
bb, addrbit : byte;
begin
{Передача байта - начало}
if Ident_intCOM1_per then
begin
if not bsready then bsready:=true;
if jCurrentTransmCom1 < 6 then Wr_byteCOM1(BufTransmCOM1[jCurrentTransmCOM1])
else RasreshCOM1_per(No);
Inc(jCurrentTransmCOM1);
end;
{Передача байта - конец}
{Прием байта - начало}
repeat
if Ident_intCOM1_pr then
begin
Rd_byteCOM1(bb,AddrBit);
if AddrBit=1 then
begin {начало обработки адресного байта}
jCurrentReceivCOM1:=0;
BufReceivCOM1[TailBufReceivCOM1,4] :=0; {4-й байт - ошибок}
end {конец обработки адресного байта}
else Inc(jCurrentReceivCOM1);
BufReceivCOM1[TailBufReceivCOM1,jCurrentReceivCOM1] := bb;
if jCurrentReceivCOM1 = 3 then
begin
if TailBufReceivCOM1 = HeadBufReceivCOM1-1 then {:ошибка переполнения BufReceiv}
BufReceivCOM1[TailBufReceivCOM1,4]:=
BufReceivCOM1[TailBufReceivCOM1,4] or $80 {!!!!!проверить}
{бит 7 байта ошибок: переполнение BufReceiv }
else Inc(TailBufReceivCOM1); {запись - в хвост} {продвижение хвоста, конец}
end;
end;{if Ident_intCOM1_pr}
until Port[Base_addrCOM1_2] and $06 = 0;
{Прием байта - конец}
Port[$20]:=$20;
end;
{$f-}
procedure InicCOM1(f_com : longint;
n_stop,
length_dat : byte);
{N_com - Номер COM-порта : 1 или 2.
f_com - частота настройки : 115200,...,115200 div n,...:
115200,57600,38400,19200,9600,4800,2400,1200,600,300,
150,134.5, 110,75,50 бод.
N_stop - число стоп-битов : 1 или 2.
length_dat - длина слова : 5,...,8 бит.
Тип четности - фиксированный девятый бит : 0 или 1 -
устанавливается и прверяется динамически в самой программе.}
var
divider : word;
ii:byte;
format:byte;
begin
Base_addrCOM1_:=MemW[$40:00];
{Port[Base_addrCOM1_] - Регистр данных приемника (при чтении) или
передатчика (при записи) при 0 в 7-м разр. Port[Base_addrCOM1_3])
и мл. байт делителя частоты, если этот бит 1}
Base_addrCOM1_1:=Base_addrCOM1_+1;
{Регистр разрешения прерываний (при 0 в 7-м разр. Port[Base_addrCOM1_3])
и ст. байт делителя частоты, если этот бит 1}
Base_addrCOM1_2:=Base_addrCOM1_+2; {Регистр идентификации прерываний}
Base_addrCOM1_3:=Base_addrCOM1_+3; {Регистр управления линией}
Base_addrCOM1_4:=Base_addrCOM1_+4; {Регистр управления модемом}
Base_addrCOM1_5:=Base_addrCOM1_+5; {Регистр состояния линии}
{Добавить сохранение параметров настройки COM-портов}
{!!!}
PBA_COM1_1:=Port[Base_addrCOM1_1];
PBA_COM1_3:=Port[Base_addrCOM1_3];
PBA_COM1_4:=Port[Base_addrCOM1_4];
{!!!}
{Инициализация регистра управления линией:Port[Base_addrCOM1_3] }
format:=0;
case n_stop of
1 : format:=format and not 4;
2 : format:=format or 4;
end;
case length_dat of
5 : format:=format and not 3;
6 : format:=format or 1;
7 : format:=format or 2;
8 : format:=format or 3;
end;
{Программирование частоты передачи.
Записываем $80 - для засылки в Port[Base_addrCOM1_] и
Port[Base_addrCOM1_1] мл. и ст. байтов делителя частоты }
Port[Base_addrCOM1_3]:=format or $80;
divider:=Round(115200.0/f_com);
Port[Base_addrCOM1_] :=Lo(divider);
Port[Base_addrCOM1_1]:=Hi(divider);
{Сброс ст.бита в Port[Base_addrCOM1_3] для использования
Port[Base_addrCOM1_] как регистра данных, а
Port[Base_addrCOM1_1] как регистра разрешения прерываний}
Port[Base_addrCOM1_3]:=format;
RasreshCOM1_pr(No);
RasreshCOM1_per(No);
{Подмена векторов ComPort}
GetIntVec($0C,isr_old_COM1);
SetIntVec($0C, @COM1_Interrupt);
{Разрешение прерываний 8259 }
Port[$21]:=Port[$21] and not $10;
{Разрешение прер. в регистре управл. модемом ! }
Port[Base_addrCOM1_4]:= 8;
UstanAddrBitCOM1(0);
end;
procedure RestoreCOM1;
begin
Port[Base_addrCOM1_1]:=PBA_COM1_1;
Port[Base_addrCOM1_3]:=PBA_COM1_3;
Port[Base_addrCOM1_4]:=PBA_COM1_4;
end;
ну и процедура непосредственно отсылки
procedure WriteBufTransmCom1(addr,value,ms,kanal);
var
aa : byte;
begin
BufTransmCom1[0]:=dd0;
BufTransmCom1[1]:=dd1;
BufTransmCom1[2]:=dd2;
BufTransmCom1[3]:=dd3;
BufTransmCom1[4]:=dd4;
BufTransmCom1[5]:=dd5;
jCurrentTransmCOM1:=0;
RasreshCOM1_per(Yes);
end;
На новых машинах изменился принцип работы ком портов
Не уверен... занимаюсь этой проблемой (ком порты) долго... никогда такой проблемы не встречал.. Юзай прямые модули....
Могу прислать... и под ХРенью работают!!!!
Как уже было сказано ошибка (error 200) может быть из-за Crt или OpCrt - прога вообще не запускается. Решение - заменить Crt и OpCrt. Кстати буду очень благодарен, если кто-нибудь подскажет где найти исправленный OpCrt, т.к у меня та же проблема: Crt исправил, а OpCrt не могу найти. Помогите пожалуйста. Спасибо.