DEMO.DESIGN
Frequently Asked Questions
 ENLiGHT Project. Новости об информационных технологиях, науке, авиации и космонавтике
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

Особенности компиляторов и языков.

 

Q: Как писать на ассемблере в Watcom C?

A: 

#pragma aux proc_name(void)  =   /
                "mov  ax,0013h"  /
                "int  10h     "  /
                modify[AH AL]
       

proc_name - название твоей поцедуры, modify[ измененные регистры ]

Если надо определить прагму в одном модуле, а использовать в другом:

void PutPixel(int x, int y, int c);
#pragma aux PutPixel parm [edx ecx eax] = /
"....."/
"....."/
modify [eax ebx ecx edx];

Q: Можно и сложно-ли писать intro/demo на Форте?

A: На практике Форт в demomaking'e если и используется, то крайне редко. Вероятно это обусловлено низкой его распространенностью (из-за RPN, отсутствия библиотек). Вопреки широко существующему мнению, надо учесть, что эффективность и объем кода проигрывают Ассемблеру. Однако никаких принципиальных препятствий не существует. Можно отметить три наиболее приличных Форта:

GPForth (Александра Ларионова) - DOS, Real mode (код 8086). В исходниках, компактный - для 64k intro довольно удачно подошел бы. Есть некоторое количество библиотек (в том числе для VGA режимов), поддержка плавающей точки.

Smal32 (Александра Ларионова и K) - DOS, Flat model (код 80386). На основе старой версии pmode extender'a. ANSI. Библиотеки для hicolor, truecolor SVGA режимов. 386 inline ассемблер. Основная проблема - трудности с обработкой прерываний (и, соответственно, с sound system) из-за pmode. Размер кода больше чем у GPForth, в том числе и за счет pmode.

SPForth (Андрея Черезова) - Win32, ANSI. Есть масса примеров. 

Вышеперечисленные реализации, а также документация, примеры, библиотеки, можно найти на http://www.forth.org.ru . Кроме того, имеет смысл почитать fido7.su.forth и comp.lang.forth.

Q: Отчего на современных компьютерах некоторые программы написанные на TurboPascal вываливаются с Runtime Error 200?

A: В модуле Crt, в процедуре delay есть ошибка - на быстрых машинах при вычислении константы происходит переполнение. Проблему можно решить либо патчем (легко найти в Интернет), ну а лучше конечно пользоваться своим delay'em. Один из вариантов патча: ищешь B9 37 00 F7 F1, Заменяешь 37 на E6.

Q: Почему когда я компилирую свою программу под TP 7 в Protected Mode, то она виснет, а если в Real mode - работает?

A: [Andrey Petrov] Возможно это связано с тем, что из под extender'a нельзя вызывать realmode прерывания.

То есть вместо
        mov     ax, <чего-то>
        ...
        int     <какой-то>

надо делать так:
        mov     rmi.eax, <чего-то>
        ...
        mov     ax, 300h            ; функция DPMI - вызов realmode interrupt
        mov     bx, <какой-то>
        xor     cx, cx              ; чаще всего
        mov     es, SEG rmi
        mov     edi, OFFS rmi
        int     31h                 ; обращение к DPMI       
       

После возврата в структуре rmi будут значения всех регистров и флагов Естественно, ты должен понимать, что значения в сегментных регистрах - это не селекторы, а именно реалмодовые сегменты, поэтому, если функция возвращает тебе информацию в буфере, на который ты должен указать сегментом:смещением, то тебе придется сначала выделить блок памяти в первом мегабайте с помощью соответствующих вызовов DPMI, взять его сегмент, вызвать нужную функцию (например, getVESAinfo ;), скопировать содержимое реалмодового буфера в свою программу (в зараннее подготовленную структуру) и затем освободить память в первом мегабайте.

Описание структуры rmi найдешь в спецификации DPMI и еще во многих местах (например, она есть в: TechHelp, RB Interrupt List, Watcom C/C++ Programmer Help, и, конечно же, в DPMI 0.9 / 1.0 spec.)

Q: Можно ли под DirectDraw писать на чистом С без СОМ и С++ ?

A: [Dmitry Sustretov, 2:5025/2275.1111] Вопрос некорректный. COM - технология создания объектов. DirectX-овские объекты созданы по спецификации COM. COM - бинарный стандарт и от языка не зависит. Можно на чем угодно писать, используя COM-объекты. Есть люди, которые пишут вместо, например,

hres = pDD->SetDisplayMode(320, 240, 32, 0, 0); // C++

вон чего

hres = pDD->lpVtbl->SetDisplayMode(pDD, 320, 240, 32, 0, 0); /* pure C */

Мой microsoft меня бережет, можно писать так :

hres = IDirectDraw_SetDisplayMode(pDD, 320, 240, 32, 0, 0); /* pure C */

И уж совсем извращенцы (и я среди них :) пишут

%define SetDisplayMode_ofs 84

mov eax, [pDD]
push dword 0
push dword 0
push dword 24
push dword 200
push dword 320
mov ecx, [eax]
push eax
call dword [ecx + SetDisplayMode_ofs]
mov [hres], eax

Hичего страшного и сложного, пишешь кусок кода на C, который использует нужную функцию и компилируешь с генерацией ..ээээ листинга. В смысле файлика, где написаны поочередно строки исходника и того, что из них получилось.
Помнить !
Регистры от вызовов портятся, кроме, afair, esi, edi, ebp.
Calling convention (WINAPI) блюсти, не забывать пропихивать последним указатель на объект. Константы из header-ов выдрать и в свой .inc пришить в удобоваримом для любимого ассемблера виде.
Я некогда за вечерок смог написать код, который создает условия для жизни :
буфер 320x240x32, легким вызовом flip_pages копируемый на экран. Экран ставится в режим предпочтительно тот же, но если отсутствует - можно и 320x240x24. DirectSound создан и к нему secondary buffer. В общем, горжусь я :) Даешь 4k/win32 !

Q: Как можно прилинковать данные (картинку, музыку) к программе на Watcom'e, в виде .OBJ файла?

A: [Lubarsky Oleg]

Приведу различные варианты:

1. Линковать откомпилированную программу с .OBJ в котором находятся твои данные, которые в свою очередь приобретают вид ".OBJ" с помощью старой, доброй утилиты BINOBJ, но это только max 64кб, отпадает.

2. Hаписать или найти прогу которая будет переводить двоичные файлы, любой длины, в такой вид: char file[_size]={1,2,3,4,5,6,7,8, ... 12,54,54};

3. "copy /b filename.exe + some.dat" в конце some.dat можно указать его длинну, чтоб проще было, тут some.dat может быть любой длины, но читать его придется с помощью IO.H, ALLOC.H.

4. Hайти некую утилитку под названием BIN2OBJ (входит в комплект "DOS32" DOS-extender) или "BINOBJ32" которая из двоичных вайлов делает .OBJ, данные в котором хранятся - _TEXT SEGMENT DWORD USE32, а затем линковать свой код с этим .OBJ, imho оптимальный метод.

(В тексте при написании названий утилит ошибки нет, одна утилита - "BINOBJ", а другая - "BIN2OBJ", а третья "BINOBJ32")

А использовать в своей проге подлинкованный код / данные можно следующим образом:

extern "C" _Type _Name;

Пример:

extern "C" char MyGfx;
char * MyGfxPointer=&MyGfx;

Затем вытащить любой байт из модуля "MyGfx" элементарно:

char MyByte;
MyByte=MyGfxPointer[OffSet];

Q: В Borland C++ можно подгружать при компилировании файлы, большие чем 64кб?

A: При компилировании - вряд ли; он же realmode, сегменты по 64k. Либо переходи на protected mode компилятор, либо fopen("my.exe"), fread(). Используй Watcom :)

Q: Hе мог бы кто-нибудь рассказать про C-- ? Очень интересно, т.к. объемы демок (несмотря на убогость эффектов впечатляют ;)

A: SPHINX C-- это смесь ASM + C/C++. Все команды написаны на ASM, а текст исходника похож на C++ При этом размер исполняемого файла получается очень маленьким... Вообщем я советую поглядеть на:
http://www.chat.ru/~sheker 
http://members.xoom.com/andesa/denis/denisfd.htm/ 
а также RU.C--


Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".