Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.06.2009, 12:18   #1
polyarnik
Пользователь
 
Регистрация: 04.06.2009
Сообщений: 11
По умолчанию

Здравствуйте, господа программисты. Нуждаюсь в помощи по следующей задаче:
"Написать программу, которая будет работать с видеопамятью. По экрану, содержащему некоторую информацию, справа налево “бежит” текстовая строка, программа должна работать резидентно. Текст, присутствовавший на экране до запуска программы, не должен портиться никаким образом.
В программе следует использовать два обработчика прерываний – прерываний таймера и прерываний клавиатуры. Прерывания таймера регламентируют скорость перемещения объекта, причем параметр, характеризующий величину скорости, необходимо задавать с клавиатуры при запуске программы. Информация о параметре, задающем скорость движения, должна выводиться на экран при запуске программы без параметров."

Подскажите, пожалуйста хотя бы как сделать, чтобы бегущая строка не стирала фоновые надписи (например результат работы команды dir). Остальное не проблема, разобрался.

Накалякал вот что:

Код:
{$M 2048,0,0}
program lab5os;
uses
  Dos,Windos,crt;
type
      TInterrupt = procedure (Flags: Word);
var
   Screen: array[1..25, 1..80, (charr, Attr)] of byte absolute $B800:$0000;
   se,st,stro:string;
   H,M,S,SS,S100,K:Word;
   i,j,kw,kw2,kz,x,y:integer;
   oldkey:byte;
     { старый обработчик }
   OldInt1C,OldInt9:TInterrupt;
   code: integer;

procedure stroka;
begin
    stro:=('  " Я Б Л О К И   П А Д А Ю Т   В   Н Е Б О "');
    k:=80-Length(stro);
     for i:=1 to k do
     stro:=stro+' ';
end;

procedure stroka1;
begin
    delete(stro,1,1);
    delay(kw);
    st:=copy(stro,1,1);
    stro:=stro+st;
    for i :=1 to 80 do
 {     Screen[kw2, i, Attr] := $1F;     }
    for j:=1 to Length(stro)-1  do
      Screen[kw2,J, charr] :=ord(stro[j]);
end;

  { обработчик прерывания Int1C }
procedure Int1C(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);interrupt;
begin
   GetTime(H, M, S, S100);
   stroka1;
   if kz=1 then
   OldInt1C(Flags);
end;

procedure Cpp;
begin
  clrscr;
  stroka;
    IF ParamCount<>2 THEN 
      begin
        writeln('Программа запущена с параметрами по умолчанию:');
        writeln('- положение строки = 5');
        writeln('- скорость строки = 10000');
      end else clrscr;
  kw:=y;kw2:=x;
  writeln;
end;

{ обработчик int 09h }
procedure Int9(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word);
            interrupt;
var
  Key:byte;
  df:byte;
 begin
  key := Port[$60];
  OldKey:=key;
  inline($9C);
  Oldint9(Flags);
 end;


begin
  GetIntVec($1C, @OldInt1C);
  SetIntVec($1C,addr(Int1C));
  GetIntVec($9,@Oldint9);
  IF ParamCount<>2 THEN    {при запуске программе передано не 2 параметра}
    begin
      x:=5;  {значения по умолчанию}
      y:=10000;
    end
  else
    begin
      VAL(ParamStr(1),x,Code);
      IF Code<>0 THEN BEGIN
      WRITELN('ОШИБКА: положение строки задано неверно');
      writeln('lab5os <положение> <скорость>'); halt; end;
      VAL(ParamStr(2),y,Code);
      IF Code<>0 THEN BEGIN
      WRITELN('ОШИБКА: скорость задана неверно');
      writeln('lab5os <положение> <скорость>'); halt; end;
    end;
  cpp;
  writeln;
  SetIntVec($9,@int9);
  keep(0);
end.
Это конечно работает, но строка стирает фон и дублируется при нажатиях Enter. Скорее всего необходимо обращение к видеопамяти напрямую по абсолютным адресам и оттуда "брать" символы, но пока из этого у меня ничего хорошего не получилось))

Последний раз редактировалось Stilet; 04.06.2009 в 12:28.
polyarnik вне форума Ответить с цитированием
Старый 04.06.2009, 12:27   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Тебе в паскале в каком режиме то?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.06.2009, 13:06   #3
polyarnik
Пользователь
 
Регистрация: 04.06.2009
Сообщений: 11
По умолчанию

В любом, но думаю в текстовом проще будет.
polyarnik вне форума Ответить с цитированием
Старый 04.06.2009, 14:05   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
в текстовом проще будет.
Да но условие
Цитата:
Текст, присутствовавший на экране до запуска программы, не должен портиться никаким образом.
Сразу отбрось. Его и в графике соблюсти трудно, а в тексте бессмысленно.
Максимум что ты добьешся это восстановление того что было на экране под надписью. Это легко. Считывай в строку из нужной координаты, а когда текст оттуда будеш передвигать пиши что сохранил в видеопамять

Вот тут примерчик накропал. ТОлько резидентом его сделай и радуйси6
Код:
uses crt;
var
 scr:array[1..25,1..80,(c,a)] of byte absolute $B800:0;
 m,s:string;
 var e,k,i:integer;
begin
  m:='qwert';       s:='';
  for i:=1 to 25 do begin
   for k:=1 to 80 do begin
    move(scr[i,k,c],s,length(m)+4);
    for e:=1 to length(m) do begin
     scr[i,k+e-1,c]:=byte(m[e]);
    end;
    delay(50);
    if keypressed then halt;
    move(s,scr[i,k,c],length(m)+4);
   end;
  end;
end.
I'm learning to live...

Последний раз редактировалось Stilet; 04.06.2009 в 14:29.
Stilet вне форума Ответить с цитированием
Старый 04.06.2009, 15:46   #5
polyarnik
Пользователь
 
Регистрация: 04.06.2009
Сообщений: 11
По умолчанию

большое спасибо, Stilet. Оставил движение по горизонтали, строка бегает целиком, не исчезая частично за границы экрана, также оставляет за собой "след":
Код:
uses crt;
var
 scr:array[1..25,1..80,(c,a)] of byte absolute $B800:0;
 m,s:string;
 var e,k,i:integer;
begin
  m:='Ne KirilicA Otobrazaetsa';       s:='';             clrscr;
  i:=5;
  while not keypressed do          begin
   for k:=1 to 80-length(m) do begin
    move(scr[i,k,c],s,length(m)+1);
    for e:=1 to length(m) do begin
     scr[i,k+e-1,c]:=byte(m[e]);
    end;
    delay(7000);
    move(s,scr[i,k,c],length(m)+1); end;
  end;
end.
Как это можно исправить? Может посимвольно пробел к строке приплюсовывать?

Последний раз редактировалось Stilet; 04.06.2009 в 16:04.
polyarnik вне форума Ответить с цитированием
Старый 04.06.2009, 16:05   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Может посимвольно пробел к строке приплюсовывать?
Зачем? Чет я не понял что у тебя за проблема...

А-а-а стоп. Кажись допер
Вот попробуй учитывать ее длину
Код:
   for k:=1 to 80-length(m) do begin
Только это смотрится некрасиво
I'm learning to live...

Последний раз редактировалось Stilet; 04.06.2009 в 16:08.
Stilet вне форума Ответить с цитированием
Старый 04.06.2009, 16:34   #7
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию

Чтоб по Enter строка не дублировалась, можно попробовать в структурах BIOS поставить 24 строки вместо 25. И монопольно рисовать на 25ой.
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/
OCTAGRAM вне форума Ответить с цитированием
Старый 05.06.2009, 10:02   #8
polyarnik
Пользователь
 
Регистрация: 04.06.2009
Сообщений: 11
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Вот попробуй учитывать ее длину
Код:
   for k:=1 to 80-length(m) do begin
Stilet, дак у меня так и написано))
OCTAGRAM, а как это будет выглядеть в программном коде применительно к моей программе?

в резидентной работе этого кода при выводе команды dir строка изчезает...

Ничего не получается, мысли уже закончились. Помогите пожалуйста, может кто-нибудь знает как это сделать...

Последний раз редактировалось Stilet; 15.06.2009 в 09:14.
polyarnik вне форума Ответить с цитированием
Старый 08.06.2009, 15:57   #9
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию

Перехватывать прерывание int 10h

Перед вызовом старого обработчика стирать бегущую строку, после вызова восстанавливать.
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/
OCTAGRAM вне форума Ответить с цитированием
Старый 15.06.2009, 09:09   #10
polyarnik
Пользователь
 
Регистрация: 04.06.2009
Сообщений: 11
По умолчанию

а можно пример программного кода?
polyarnik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
бегущая строка djes Паскаль, Turbo Pascal, PascalABC.NET 6 22.04.2009 21:11
Бегущая строка. blackstersl Общие вопросы Delphi 3 20.02.2009 09:43
Бегущая строка vitamin.rulez Помощь студентам 8 28.01.2009 21:48
Бегущая строка и about Патрон Общие вопросы Delphi 12 02.06.2008 22:31