Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Доступ к экрану через BIOS. Помогите!  (Прочитано 14770 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Oksy
Гость
« : 18-03-2006 06:24 » 

Люди, помогите, если кто знает.
Материал взят из книги Г.Шилдта(название не знаю):

Сохраниение части экрана
Прерывание 16, функция 8 возвращает символ из текущей позиции курсора в AL и его атрибут в AH. Функция save_video(), показанная здесь, считывает часть экрана, сохраняет информацию в буфер, и очищает эту часть экрана.

void save_video(startx,endx,starty,endy,buf_ptr)
int startx,endx,starty,endy;
unsigned int *buf_ptr;
{
union REGS r;
register int i,j;

for(i=starty;i for(j=startx;j goto_xy(j,i);
r.h.ah=8; /* функция чтения символа */
r.h.bh=0; /* видео страница */
*buf_ptr++ = int86(0x10,&r,&r);
putchar(' '); /* очистка экрана */
}
}

Восстановление экрана
Восстановление экрана после сделанного выбора из меню, заключается просто в записи предварительно запомненной информации назад в видео память. Для того, чтобы сделать это, используйте прерывание 16, функцию 9, которая требует, чтобы символ был в AL, аттрибут в BL, видео страница в ВН, а количество записываемых символов в CX (в нашем случае 1). Функция restore_video(), описанная здесь, помещает информацию из буфера, на который указывает buf_ptr, на экран, заданный начальными и конечными координатами X и Y.

void restore_video(startx,endx,starty,endy,buf_ptr)
int startx,endx,starty,endy;
unsigned int *buf_ptr;
{
union REGS r;
register int i,j;

for(i=starty;i for(j=startx;j goto_xy(j,i);>BR? r.h.ah=9; /* функция записи символа */
r.h.bh=0; /* видео страница */
r.x.cx=1; /* число повторений символа */
r.h.al=*buf_ptr++; /* символ */
r.h.bl=*buf_ptr++; /* атрибут */
*buf_ptr++ = int86(0x10,&r,&r);
}
}

Как я поняла, здесь используется "старомодный" стиль ситаксиса.
Вопрос:
как это будет выглядеть в стиле "модерн"?
Пробовала преобразовать сама. Почти получилось, но функция restore_video(...) возвлащает на экран белиберду, скорее всего из-за непереведенного мной >BR? в функции restore_video(...), эта часть просто отсутствует в моем варианте.
Кто знает, что это такое и как оно выглядит в "модерне"?
« Последнее редактирование: 13-12-2007 20:59 от Алексей1153++ » Записан
Oksy
Гость
« Ответ #1 : 18-03-2006 08:49 » new

Так выглядит мой вариант:
#include <dos.h>
#include <conio.h>
#include <stdio.h>
void save_video(int x1, int y1, int x2, int y2,  unsigned int *buf)
{
 union REGS r;
 register int i, j;
 for(i=y1;i<y2;i++)
 {
   for(j=x1;j<x2;j++)
   {
    gotoxy(j,i);
    r.h.ah=8;
    r.h.bh=1;
    *buf++=int86(0x10,&r,&r);
    putchar(' ');
   }
 }
}

void restore_video(int x1, int y1, int x2, int y2, unsigned int *buf)
{
 union REGS r;
 register int i, j;
 for(i=y1;i<y2;i++)
 {
   for(j=x1;j<x2;j++)
   {
    gotoxy(j,i);
    r.h.ah=9;
    r.h.bh=0;
    r.x.cx=1;
    r.h.al=*buf++;
    r.h.bl=*buf++;
    *buf++=int86(0x10,&r,&r);
   }
 }
}

void main()
{
 clrscr();
 _setcursortype(_NOCURSOR);
 int i=0;
 for(i; i<=2078; i++)
 printf("0");
 unsigned int *buf;
 getch();
 save_video(10,5,13,8,buf);
 getch();
 restore_video(1,1,4,4,buf);
 getch();
}
« Последнее редактирование: 13-12-2007 20:59 от Алексей1153++ » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 18-03-2006 11:42 » 

Код:
for(i=starty;i for(j=startx;j goto_xy(j,i);
r.h.ah=8; /* функция чтения символа */
r.h.bh=0; /* видео страница */
*buf_ptr++ = int86(0x10,&r,&r);
putchar(' '); /* очистка экрана */
}
}
Здесь же синтаксическая ошибка. Не верю, чтобы работало. Так циклы отродясь (языка C) не писались.

Далее по сути задачи. Можно, конечно, использовать прерывание 10h (видео в BIOS), но "белые" люди со времён распространения CGA и более развитых адаптеров работают напрямую с видеопамятью.

Для цветного текстового режима видеопамять экрана начинается по адресу B800h:0000h. Каждый символ описывается двумя байтами: первый байт - ASCII код символа, второй байт - цветовой атрибут (тот, что устанавливается функцией textattr - в помощи Turbo C описано, как им пользоваться). Такими парами байтов описывается весь экран построчно от левого верхнего угла. Т.е. первые 160 байт описывают символы первой строки экрана, вторые 160 байт - вторую строку и т.д. Всего для обычного текстового режима используется 80*25*2=4000 байт. Соответственно, несложными арифметическими преобразованиями можно получить адрес конкретного знакоместа и прочитать записанный там символ и его цвет. Можно осуществлять и запись.

Поищу примеры...

« Последнее редактирование: 13-12-2007 21:00 от Алексей1153++ » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
nikedeforest
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 18-03-2006 12:39 » 

Вот пример реализации функции putpixel. В файле отчет по лабораторной и текст программы. Вроде там должно быть все понятно.
P.S. Прошу особо не придираться, это я достал лабораторную со второго курса Улыбаюсь.

* Лаб раб№2опи+прога.doc (42 Кб - загружено 1172 раз.)
Записан

ещё один вопрос ...
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 18-03-2006 13:09 » 

Примеров не нашёл, поэтому сам собрал программку.
Код:
#include <conio.h>
#include <dos.h>
#include <stdlib.h>

/* ОПРЕДЕЛЕНИЕ ВИДЕОПАМЯТИ */

/* Структура знакоместа в видеопамяти */
struct videochar
{
char ascii; /* ASCII код символа */
char color; /* цветовой атрибут символа */
};

/* Определение типа видеопамяти */
typedef struct videochar far *videomem;

/* Адресация переменной video таким образом, чтобы через
эту переменную можно было обращаться к
видеопамяти */
videomem video = (videomem)MK_FP(0xB800, 0);

/* ФУНКЦИИ РАБОТЫ С ВИДЕОПАМЯТЬЮ */

/* Получает указатель на знакоместо в видеопамяти, находящееся
в позиции x, y */
videomem get_vidchptr(int x, int y)
{
/* Перемещаем указатель на строку y - отсчитываем y-1
раз по 80 знакомест */
/* Затем перемещаемся в столбец x - отсчитываем x-1
знакоместо */
return video + (y - 1) * 80 + (x - 1);
}

/* Сохранение куска изображения в буфер */
void save_video(int x1, int y1, int x2, int y2,
struct videochar **buffer)
{
int x, y;
struct videochar *iter;
/* Определяем, сколько нам нужно памяти для буфера */
size_t bufsize = (y2 - y1 + 1) * (x2 - x1 + 1) *
sizeof(struct videochar);
/* Выделяем память под буфер */
*buffer = (struct videochar *)malloc(bufsize);
/* Чтобы не потерять указатель на начало буфера,
пользуемся вспомогательным указателем. */
iter = *buffer;
for(x = x1; x <= x2; ++x)
for(y = y1; y <= y2; ++y, iter++)
/* Копируем знакоместо из
видепамяти в буфер */
*iter = *get_vidchptr(x, y);
}

/* Восстановление куска изображения из буфера */
void restore_video(int x1, int y1, int x2, int y2,
struct videochar **buffer)
{
int x, y;
struct videochar *iter;
/* Чтобы не потерять указатель на начало буфера,
пользуемся вспомогательным указателем. */
iter = *buffer;
for(x = x1; x <= x2; ++x)
for(y = y1; y <= y2; ++y, iter++)
/* Копируем знакоместо из
буфера в видепамять */
*get_vidchptr(x, y) = *iter;
/* Освобождаем память буфера */
free(*buffer);
}

/* ОСНОВНАЯ ПРОГРАММА */

int main()
{
struct videochar *buffer;
/* Перед запуском заполните чем-нибудь экран для
наглядности. */
getch();
/* Запоминаем кусок экрана между 10 и 70 столбцами
и 10 и 20 строками */
save_video(10, 10, 70, 20, &buffer);
/* Очищаем экран - убеждаемся, что картинки нет */
clrscr();
getch();
/* Восстанавливаем кусок экрана - убеждаемся, что всё
работает */
restore_video(10, 10, 70, 20, &buffer);
getch();
return 0;
}
Обращаю внимание, что в программе нет проверок при работе с памятью. Это означает, что:
- перед сохранением буфер ничего не содержит, иначе будет утечка памяти;
- оперативной памяти на буфер всегда хватает - факт выделения не проверяется - иначе будет ошибка;
- видеопамять в самом деле начинается с B800:0000, т.е не какой-нибудь там монохромный Hercules 20-илетней давности;
- размер восстанавливаемого изображения совпадает с размером сохраняемого, иначе могут быть ошибки.

Последний случай можно обойти, используя такую структуру видеобуфера:
Код:
struct videobuffer
{
int x1, y1, x2, y2;
struct videochar *buffer;
};
т.е. чтобы размеры и позиция сохранялись вместе с видеобуфером и случайно не потерялись бы где-нибудь в недрах программы, тогда при восстановлении не нужно будет передавать координаты области восстановления.
« Последнее редактирование: 07-04-2006 05:34 от dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 18-03-2006 13:17 » 

Вот ведь... Чего было мучаться...

в conio.h есть функции gettext и puttext - они делают всё, что нужно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
nikedeforest
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 18-03-2006 13:25 » 

Улыбаюсь
Будем надеяться не напрасно ты мучался, ведь возможно для Oksy важно поработать с видеопамятью напрямую.
Записан

ещё один вопрос ...
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #7 : 18-03-2006 15:15 » 

Цитата
for(i=starty;i for(j=startx;j goto_xy(j,i);>BR?
скорее всего книга в HTML и СИ-шнуй знак "<" воспринялся как открытие HTML-тэга
Записан

Удачного всем кодинга! -=x[PooH]x=-
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 18-03-2006 16:51 » 

Цитата
Будем надеяться не напрасно ты мучался, ведь возможно для Oksy важно поработать с видеопамятью напрямую.
Это врядли. Если только "для общего развития", но совсем не для решения задачи. К тому же gettext и puttext и так работают с видеопамятью напрямую (если directvideo включено, иначе через BIOS).
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Oksy
Гость
« Ответ #9 : 19-03-2006 07:16 » 

dimka, спасибо за подробный ликбез!:) Как разгребусь с дипломом, сразу же займусь "общим развитием"Улыбаюсь
Записан
МАКСИМ.
Гость
« Ответ #10 : 06-04-2006 17:19 » 

привет !я тоже считал Шилдта и сталкнулся с проблемой  функций Save_Video()и Restore_Video(). там с предачей   аттрибута байта в функцию. 

у меня так получилось в BORLAND C 3.1
c этими функциями:

/*------save screen-------*/
void Save_Video(int startx,int endx,
       int starty,int endy, unsigned  int  *buf_ptr){

 union REGS r;
 register int i,j;

 for(i = starty;i<endy; i++)
    for(j = startx;j<endx; j++) {
   goto_xy(j,i);
   r.h.ah = 8;
   r.h.bh = 0;
   *buf_ptr++ = int86(0x10,&r,&r);
   putchar(' ');//clear screen
    }
}

/*-----return of screen-----*/
void  Restore_Video(int startx,int endx,
            int starty,int endy, unsigned  int  *buf_ptr){
    union REGS r;
    register int i,j;

   for( i=starty; i<endy; i++)
       for( j=startx; j<endx; j++){
    goto_xy(j,i);
    r.h.ah = 9;//func write simbol
    r.h.bh = 0;//videopage
    r.x.cx = 1;// 1 simbol
    r.h.al = *buf_ptr++;
    r.h.bl = 0x90;// !!! attrib - цвет фона(9)  и цвет символа(0) я задал сам;
    int86(0x10,&r,&r);// !
       }
}

с синтаксисом в стиле "модерн" я немного не понял что имелось ввиду.
 это программирование на Си под виндос?Не понял
 
« Последнее редактирование: 13-12-2007 21:01 от Алексей1153++ » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #11 : 06-04-2006 19:50 » 

МАКСИМ., В виндовсе практически нельзя напрямую лазить в видеопамять. Так что, покажи не понятный участок кода. Будем разбираться и объяснять.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
МАКСИМ.
Гость
« Ответ #12 : 07-04-2006 01:28 » 

Finch, я через функции BIOS-а  только начал работать с видеопамятью.а про функции(Save_Video()и Restore_Video() ) что я писал - я их реализовал в своих программах.
я в DOs-е  пишу программки.до винды еще не дошел.но немного программировал на делфи, ассемблере в винде. 
А вообще программировать хочу научиться и перенять некоторый опыт  от профессионалов.сейчас и я изучаю Си и по возможности  Ассемблер.

     
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines