Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с видеопамятью, в C++ Builder под WinXP 
V
    Опции темы
Kuvaldis
Дата 24.6.2006, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: нет
Всего: 61



Про прерывание в WinXP  мне объяснили. Еще  вопрос. В ассемблерной вставке почему-то не получается не то, что записать, а просто ПРОЧИТАТЬ то , что находится по адресу видеопамяти с 0B800h. То же с байтом клавиатуры. Я же даже ничего не изменяю.
Эти данные по другим адресам или...?  А программа запущенная не из среды, выдает ошибку, в среде - зависание.
Буду рад ответам. Заранее спасибо. 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
setty
Дата 24.6.2006, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 8.6.2006
Где: Украина

Репутация: нет
Всего: нет



возможно проблема в том что винда тебя фиг пустит напрямую к видеопамяти. тут работать приходится немного не так как под досом, юзать надобно соответствующие API, а если хочеш прерываниями то придёца на ring0 кодить 
PM MAIL   Вверх
Kuvaldis
Дата 24.6.2006, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: нет
Всего: 61



Цитата

а если хочеш прерываниями то придёца на ring0 кодить 


Дайте ссылку, плз, где про это почитать, как зайти в этот ring-0 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
setty
Дата 24.6.2006, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 8.6.2006
Где: Украина

Репутация: нет
Всего: нет



инфу, если не найдёш я те ночью скину (как и тот исходник). Это довольно интересная но между тем довольно тяжолая тема, сам я несилён в этом. Могу лиш посоветовать на первых порах не парится с этим, практически любой вопрос сводится к тому какой набор nativ APIs тебе необходимо использовать. Ты можеш писать символы в консоль, устанавливать позицию курсора, задавать цвет и фон символов, устанавливать заголовок консоли, создавать и удалять консоли, перенаправлять ввод/вывод и все это риализуется в usermode посредством родных апи. Добавлю ктомуже что под Windows запустить код в ring0 доволно проблематично. Прийдётся писать драйвер. Хотя есть технологии перехода из в 3го в 0е однако они требуют знания предмета. 
PM MAIL   Вверх
Romikgy
Дата 24.6.2006, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: нет
Всего: 146



Kuvaldis, ты можешь написать конкретно что тебе нужно сделать и в какой оси? 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
oleg1973
Дата 26.6.2006, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 2
Всего: 34



какой вы бред несете
зачем там ринг0 ? в винде есть и direct draw и direct 3D и openGL
рисуй нехочу

п.с.
поиск по форуму рулит 


--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
setty
Дата 26.6.2006, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 8.6.2006
Где: Украина

Репутация: нет
Всего: нет



ну спрашивал человек про прерывания и видеопамять... 
PM MAIL   Вверх
rsm
Дата 26.6.2006, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: нет
Всего: 62



Kuvaldis, как вариант, пиши под ДОС что хочешь, а запускать будешь в DosBox. 
PM MAIL   Вверх
setty
Дата 27.6.2006, 02:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 8.6.2006
Где: Украина

Репутация: нет
Всего: нет



я тоже задавал помнится подобные вопросы когда с доса на виндозу перешол програмить... понимаю как поначалу все может выглядеть дико, такчто, Kuvaldis, если чё обращайся...
а вапще туторы икселиона те в помощ ) 
PM MAIL   Вверх
sgi1981
Дата 31.7.2006, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 1
Всего: 10



В общем используйте АПИ-функцию SetDIBitsToDevice.
Сначала я приведу цитату, а потом свое мнение.

Цитата со страницы 
http://vsokovikov.narod.ru/Msdn_api/Global...itstodevice.htm
Цитата

Функция SetDIBitsToDevice устанавливает пиксели в заданном прямоугольнике устройства, которое связано с целевым контекстом устройства, используя данные о цвете из аппаратно-независимого растрового формата (DIB).

Windows 98/Me, Windows 2000/XP: SetDIBitsToDevice была дополнена, чтобы дать возможность формат изображения JPEG или PNG передавать как источниковое изображение.

Синтаксис
Код

int SetDIBitsToDevice(
  HDC hdc,                 // дескриптор DC
  int XDest,               // x-коорд. верхнего левого угла приемника
  int YDest,               // y-коорд. верхнего левого угла приемника
  DWORD dwWidth,           // ширина прямоугольника источника
  DWORD dwHeight,          // высота прямоугольника источника
  int XSrc,                // x-коорд. нижнего левого угла источника
  int YSrc,                // y-коорд. нижнего левого угла источника
  UINT uStartScan,         // первая строка развертки в массиве
  UINT cScanLines,         // число строк развертки
  CONST VOID *lpvBits,     // массив битов DIB
  CONST BITMAPINFO *lpbmi, // информация о точечном рисунке
  UINT fuColorUse          // RGB или индексы палитры
);

Параметры

hdc
[in] Дескриптор контекста устройства.

XDest
[in] Определяет x-координату верхнего левого угла приемного прямоугольника, в логических единицах измерения.

YDest
[in] Определяет y-координату верхнего левого угла приемного прямоугольника, в логических единицах измерения.

dwWidth
[in] Определяет ширину секции DIB, в логических единицах измерения.

dwHeight
[in] Определяет высоту секции DIB, в логических единицах измерения.

XSrc
[in] Определяет x-координату нижнего левого угла DIB, в логических единицах измерения.

YSrc
[in] Определяет y-координату нижнего левого угла DIB, в логических единицах измерения.

uStartScan
[in] Определяет начальную строку развертки DIB.

cScanLines
[in] Определяет число строк развертки DIB, содержащиеся в  массиве, на который указывает параметр lpvBits.

lpvBits
[in] Указатель на данные о цвете формата (DIB), сохраненные как массив байтов. Подробную информацию см. ниже в разделе Замечания.

lpbmi
[in] Указатель на структуру BITMAPINFO, которая содержит информацию о  DIB.

fuColorUse
[in] Определяет, содержит ли член bmiColors структуры BITMAPINFO значения (RGB) чистого красного, зеленого, синего цветов  или индексы палитры. Подробную информацию, см. ниже в разделе Замечания.

Параметр fuColorUse  должен быть одним из нижеперечисленных значений.


Значение  Предназначение
DIB_PAL_COLORS  Таблица цветов состоит из массива 16-битовых индексов текущей выбранной логической палитры.
DIB_RGB_COLORS  Таблица цветов содержит значения  констант RGB.

Возвращаемые значения

Если функция завершается успешно, возвращаемое значение - число установленных строк развертки.

Если функция завершается с ошибкой, величина возвращаемого значения - нуль.


Из страницы http://doc.mpv.ru/steps/mfc/detail/30.html

Цитата

Структура BITMAPINFO - это набор двух структур. Она объявлена в файле wingdi.h,

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;

Итак, первая структура у нас это BITMAPINFOHEADER, она содержит информацию о растре и вот её содержание.

typedef struct tagBITMAPINFOHEADER{
        DWORD      biSize;
        LONG       biWidth;
        LONG       biHeight;
        WORD       biPlanes;
        WORD       biBitCount;
        DWORD      biCompression;
        DWORD      biSizeImage;
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

biSize - размер структуры в байтах и должен быть равен 40 байтам.

biWidth & biHeight - содержат высоту и ширину растра в байтах.

biPlanes - смысл непонятен, так как здесь всегда 1.

biBitCount - число битов на пиксель может быть разное и зависит от типа палитры. Могут быть числа 1,2,4,8,24

biCompression - алгоритм сжатия, вот значения:

0 нет
1 RLE-8
2 RLE-4

biSizeImage - размер растра в байтах и бывает нужно только для сжатых растров.

biXPelsPerMeter & biYPelsPerMeter - показывают сколько пикселей на метр, обычно 0 smile

biClrUsed & biClrImportant - количество используемых цветов и количество значимых цветов. Обычно 0 :-)

Следующая структура - это RGBQUAD описанная в файле wingdi.h. Это не одна структура, а набор структур, которые представляют из себя паритру.

typedef struct tagRGBQUAD {
        BYTE    rgbBlue;
        BYTE    rgbGreen;
        BYTE    rgbRed;
        BYTE    rgbReserved;
} RGBQUAD;

Кто знаком с понятием цветов, то это набор цветов RGB, то есть интенсивности составляющей красной, зеленой и синей. Количество структур зависит от типа растра. Если растр на 256 цветов, то и структур будет 256. Цветовая таблица вообще отсутсвует в растрах с 24 битным изображением Hi Color.


А мое мнение таково, я не нашел более быстрого способа передавать изображение в WINDOWS-прикладной программе. Использовать эту функцию нужно таким образом.
Вначале запишем структуру BITMAPINFO.
В блоке памяти (массиве) запишем определенным образом двойные слова. Каждое двойное слово кодирует пиксел. Потом выводим этот массив на экран (можно в любую прямоугольную область экрана).

И для оформления массива пикселов лучше программировать на Assembler с использованием инструкций расширений SSE, SSE2 АЛУ процессора.

А вот моя демонстрационная программа, демонстрирующая возможности функции SetDIBitsToDevice.
После запуска программы - поведите мышкой в разные стороны и убедитесь в том, что постороенное на весь экран изображение вообще не отстает от мыши !
Затем нажмите кнопку мыши и посмотрите на эффект.
Выход из программы - клавиша ESC.
Компонентов на форме не нужно.
Код

#include <vcl.h>
#pragma hdrstop

#include "Unit1effectSetDIBitsToDevice.h"
#include "math.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
unsigned int masim[4000000];
tagBITMAPINFO* bi= new tagBITMAPINFO;
void* p;
unsigned int  DestX1, DestY1, Width1, Height1, SrcX1, SrcY1, StartScan, NumScans,
  X1,X2,Y1,Y2;
HDC D;
unsigned int mas1ht[4];
unsigned int mas2Yj[4];
unsigned int mas3i[4];
unsigned int mas4_4[4];
unsigned int mas5m[4];
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormCreate(TObject *Sender)
{
Form1->BorderStyle=bsNone;
Form1->WindowState=wsMaximized;
bi->bmiHeader.biSize=sizeof(bi->bmiHeader);
bi->bmiHeader.biWidth=1024;
bi->bmiHeader.biHeight=768;
bi->bmiHeader.biPlanes=1;
bi->bmiHeader.biCompression=0;
bi->bmiHeader.biBitCount=32;
bi->bmiHeader.biSizeImage=1024*768*4;
bi->bmiColors->rgbBlue=0;
bi->bmiColors->rgbGreen=0;
bi->bmiColors->rgbRed=0;
bi->bmiColors->rgbReserved=0;
DestX1=0;
DestY1=0;
Width1=1024;
Height1=768;
SrcX1=0;
SrcY1=0;
StartScan=0;
NumScans=1024;
p=masim;
D=GetDC(Form1->Handle);
//D=CreateDC("DISPLAY",0,0,0);
mas4_4[0]=4;
mas4_4[1]=4;
mas4_4[2]=4;
mas4_4[3]=4;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
unsigned int x,y,i,j,c,r,Yj;
SrcY1=0;
DestY1=0;
asm{
mov esi,X;
mov edi,Y;
mov ecx,0;
mov j,768;
@c2:cmp j,0;
jz @2;
mov i,0;
mov eax,edi;
sub eax,j;
imul eax;
mov Yj,eax;
@c1:cmp i,1024;
jz @3;
mov eax,esi;
sub eax,i;
imul eax;
add eax,Yj;
shl eax,8;
mov masim+ecx*4,eax;
inc ecx;
inc i;
jmp @c1;
@3:dec j;
jmp @c2;
@2:
};
SetDIBitsToDevice(D,DestX1,DestY1,Width1,Height1,SrcX1,SrcY1,StartScan,NumScans,p,bi,0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int X, int Y)
{
unsigned int x,y,i,j,c,r,ht,ht1,c1,Yj,b1,ecx1;
unsigned int v1000=100;
tagPOINT tp1;
ht=0;
asm
{
mov c1,0;
@c3:cmp c1,1500;//ñ÷åò÷èê !!!
jz @1;
}
GetCursorPos(&tp1);
asm{
mov esi,dword ptr tp1;
mov edi,dword ptr tp1+4;
inc ht;
mov eax,ht;
mul eax;
imul v1000;
mov ht1,eax;
mov mas1ht,eax;//Äëÿ XMM
mov mas1ht+4,eax;
mov mas1ht+8,eax;
mov mas1ht+12,eax;
mov mas5m,esi;
mov mas5m+4,esi;
mov mas5m+8,esi;
mov mas5m+12,esi;
mov ecx,0;
mov j,768;
mov b1,0;
mov SrcY1,0;
mov DestY1,0;
//XMM
movdqu xmm7,dqword ptr mas1ht;
movdqu xmm4,dqword ptr mas5m;
movdqu xmm3,dqword ptr mas4_4;
@c2:cmp b1,768;
jz @22;
cmp j,0;
jz @2;
mov i,0;
mov eax,edi;
sub eax,j;
imul eax;
mov Yj,eax;
mov mas2Yj,eax;//Äëÿ XMM
mov mas2Yj+4,eax;
mov mas2Yj+8,eax;
mov mas2Yj+12,eax;
mov mas3i,0;
mov mas3i+4,1;
mov mas3i+8,2;
mov mas3i+12,3;
//XMM
movdqu xmm6,dqword ptr mas2Yj;
movdqu xmm5,dqword ptr mas3i;
@c1:cmp i,256;//1024;
jz @3;
movdqa xmm0,xmm4;
psubd xmm0,xmm5;
pmaddwd xmm0,xmm0;
paddd xmm0, xmm6;
psubd xmm0,xmm7;
pslld xmm0,8;
movdqu dqword ptr masim+ecx,xmm0;
add ecx,16;
paddd xmm5,xmm3;
inc i;
jmp @c1;
@3:dec j;
inc b1;
jmp @c2;
@22:mov b1,0;
push DIB_RGB_COLORS;
push dword ptr bi;
push dword ptr p;
push dword ptr 768;//NumScans;
push dword ptr StartScan;
push dword ptr SrcY1;
push dword ptr SrcX1;
push dword ptr Height1;
push dword ptr Width1;
push dword ptr DestY1;
push dword ptr DestX1;
push dword ptr D;
call SetDIBitsToDevice;

mov ecx,0;
jmp @c2;
@2:
inc c1;
jmp @c3;
@1:mov StartScan,0;
};
}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormShortCut(TWMKey &Msg, bool &Handled)
{
if (Msg.CharCode==27) Application->Terminate();        
}
//---------------------------------------------------------------------------
  

Это сообщение отредактировал(а) sgi1981 - 31.7.2006, 11:55


--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
oleg1973
Дата 18.8.2006, 03:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 2
Всего: 34



sgi1981, 
а не быстрее будет через директдрав пИсать ?

тоесть рисую в бекбуфере а потом копирую в примари сурфейс


--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
sgi1981
Дата 18.8.2006, 07:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 1
Всего: 10



Цитата(oleg1973 @ 18.8.2006,  03:54)
тоесть рисую в бекбуфере


Ну а я же и рисую в буфере !
Код

@c1:cmp i,1024;
jz @3;
mov eax,esi;
sub eax,i;
imul eax;
add eax,Yj;
shl eax,8;
mov masim+ecx*4,eax;записываем в БУФФЕР
inc ecx;
inc i;
jmp @c1;


И для тех кто не понял, объясню - в данном случае masim - это указатель на буффер.

Цитата(oleg1973 @ 18.8.2006,  03:54)
а потом копирую в примари сурфейс


Ну а я что делаю ?
Разве я не копирую буффер в память видеоадаптера ?
Код

push DIB_RGB_COLORS;
push dword ptr bi;
push dword ptr p;
push dword ptr 768;//NumScans;
push dword ptr StartScan;
push dword ptr SrcY1;
push dword ptr SrcX1;
push dword ptr Height1;
push dword ptr Width1;
push dword ptr DestY1;
push dword ptr DestX1;
push dword ptr D;
call SetDIBitsToDevice;


Здесь копирование из буффера делает функция SetDIBitsToDevice

Это сообщение отредактировал(а) sgi1981 - 18.8.2006, 07:37


--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
oleg1973
Дата 18.8.2006, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 2
Всего: 34



Код


comcall DDSBack,LockSurface,0,ddsd,DDLOCK_WAIT,0
mov edi,[ddsd.lpSurface] // адрес бэкбуфера в видепамяти
mov [edi],0xffffffffh // рисуем белую точку
comcall DDSBack,UnlockSurface,0
comcall DDSPrimary,Flip,0,0  // а тут делаем хардварный обмен страницами видеопамяти




--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
sgi1981
Дата 19.8.2006, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 16.3.2006

Репутация: 1
Всего: 10



Цитата(oleg1973 @ 18.8.2006,  03:54)
sgi1981, 
тоесть рисую в бекбуфере а потом копирую в примари сурфейс
Код

comcall DDSBack,LockSurface,0,ddsd,DDLOCK_WAIT,0
mov edi,[ddsd.lpSurface] // адрес бэкбуфера в видепамяти
mov [edi],0xffffffffh // рисуем белую точку
comcall DDSBack,UnlockSurface,0
comcall DDSPrimary,Flip,0,0  // а тут делаем хардварный обмен страницами видеопамяти

Понимаешь.
В твоем случае данные на самом деле данные не копируются из БЭКБУФФЕРа в ПРИМАРИСУРФЕЙС, а просто обе страницы видеопамяти меняются ролями. Видеоадаптер переключает адрес отображаемой части видеопамяти с одного значения на другое, и данные для передачи на монитор берутся просто уже из другого адреса.

Если процессор непосредственно обращается к видеопамяти видеоконтроллера и пишет туда данные при выполнении написанных тобой инструкций - то действительно, такой путь наиболее быстрый !
А я и хотел узнать как так сделать, и ты подсказал. Но из тех пяти строчек кода понятна только часть сути, поскольку для того, чтобы они работали нужно ещё описание чего-то...

В общем нужно будет книгу по DirectX искать.




--------------------
Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства.
PM MAIL   Вверх
oleg1973
Дата 20.8.2006, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


asm fanat
****


Профиль
Группа: Экс. модератор
Сообщений: 3283
Регистрация: 16.7.2003
Где: Italy

Репутация: 2
Всего: 34





--------------------
SST 465555
icq 200-512-712
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для Windows/DOS"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для Windows/Dos | Следующая тема »


 




[ Время генерации скрипта: 0.0685 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.