Tato skolicka se ponekud lisi od ostatnich, protoze se nevenuje unixu ale dosu(ne ja jsem se nezblaznil a rozhodne na nej neprechazim - kazdy snad vi, ze prechod je mozny jen jednim smerem, ale mam pocit, ze unixoveho programatora muze zaujmount to, ze jeho programy by mozna slo spustit i pod dosem) Budu se venovat baliku DJGPP. Neni to jenom povrchni popis. Chci se venovat i ruznym figlum, na ktere jsem prisel. Je to zajimave i pro ty co duverne znaji verze starsi nez 2.0. Doslo k dulezitym zmenam. Uzivatelum unixu se omlouvam za prilisnou detailnost v popisu GNUC (ktere jiste znaji) ale psal jsem to i pro uzivatele DOSu Ty, ktere uvod nezajima muzou prejit na "cast pro pokrocile" Co tedy o tom rika manual?(tohle muzete preskocit) ================================================== DJGPP je port GNUC/C++ compileru a vyvojovych prostredku pro 32bitove protected modove prostredi na Intel compatibilnich CPU pod MS-DOSem a kompatibilnich operacnich systemech. (Cesky to znamena GCC pro DOS) Od verze v2.0 nepotrebuji oddeleny extender, jenom DPMI server v behu. (cesky:kompiluje do jednoho exace) DJGPP zahrnuje volne siritelni 32-bitovy DPMI server, ktery podporuje 32-Bitovy, 4BG flat adresovatelny prostor a az 256 MBytes swapovaciho prostoru. (cesky:exace mame prece jenom dva, ten druhy je dost dobry DPMI server) Kompiler produkuje 32bitovy protected modovy kod a GNU nastroje preportene pro dos poskytoji idealni prostredi pro porteni UNIXovych aplikaci. (ceky:kopiruje to unix) Je take vhodny pro psani novych programu. (samozdrejme) DJGPP je zadarmo a tak je idealni pro vytvareni volne siritelnych i komercnich programu. DJ Delorie (dj@delorie.com) je hlavni vyvojar a maintainer, ale kazdy muze pomoci Nevim presne, co skratka djgpp znamena, ale vysvetluji si ji takto: dj jsou krestni jmena autora - DJ Delorie a gpp je dosacky prepis d++. Snad je to vporadku. A co to znamena? ================ Asi takhle: pod djgpp muzete delat 32bit programy stejne jako pod drahym watcom c a dlouhym dos4gw. S tim rozdilem, ze vase programy budou kompilovany lepsim kompilerem (mene bug a nekolikanasobne lepsi optimalizace), budou vyuzivat kratsi a dle mych vzkusenosti stabilnejsi extender. Takze minimalni velikost spustitelneho souboru je 7KB plus asi 14KB dpmi serveru, coz je 20KB kodu narozdil od watcomackych 300KB. Navic vase programy budou stabilnejsi nez ty v dos4gw. Jedinim me znamym prikladem vetsiho programu v djgpp je quake (pokracovani dooma od ID) kteri na to presli kdyz zjistili ze doom zkompilovani v djgpp je az 2krat rychlejsi. Muzete se take podivat na meho xaose(realtime zoomer fractalu) na ftp://ftp.ta.jcu.cz/pub/msdos/hubicka/xaos-dos.zip Otesoval jsem je na: - cisty dos - dos z diskety(tady pada dos4gw) - windows 3.1 - windows95 - linuxacky dosemu(tady padaji borlandi) - emm386 (tady padaji borlandi) - qemm 7.53 + qdpmi(tady pada dos4gw i borlandi) - qemm 8.0 - z combi ramdisku(nema rada vetsina dos4gw aplikaci, padaji borlandi) - 386max+dpmi server(padaji borlandi) - pmode nebo swdpmi dpmi servery(tady pada dos4gw i borlandi) - pisou,ze pracuje pod novejsimi OS/2, Windows NT Budou mit potize nebo nepobezi na: - xt,286 - novell dos s jeho dpmi a qemm7.5 s qdpmi muzou zpusobit pad aplikace, protoze maji buggy dpmi servery Snadna kompatibilita s(stejny kompiler, obcas jine knihovny) - UNIX(mnoho (skoro vsechny) unixy i procesory) - Amiga, Atari - OS/2 - Windows (RSXWDK) - Win NT/Win 95 (cygnus project) - dalsi, na ktere jsem zapomel.... Co mate k dispozici =================== - GCC,GXX,OBJC - velice vykony kompiler z opravdu dukladnou optimalizaci (120KB zdrojaku kompilovat do 50KB kodu zase neni az tak zvlastni pomer, dosahuje ho vetsina mych zdrojaku, kde nejsou komentare) A podporuje C,C++, objective C - GDB, EDEBUG, E32DEBUG, FSDB - Nekolik debuggeru (radkove gdb,edebug a fulscreen borland style fsdb, - GPROF - profiler, - kompiler ansi-pascalu i jinych (pa)jazyku, - MAKE - utilita nutna ke kompilaci - INFO - utilita nutna ke cteni dokumentace - GRX, Allegro, Jlib, xlib bcc2grx - graficke knihovny (jedna normalni, dve pro hry, moznost prime kompilace bgi aplikaci a knihovna pro xmody) s podporou: - vesa1.2v - vesa2 - s3 - modu X a dalsi karty - RHIDE - skoro borlandi IDE, s barvickami, kompilaci, online helpem ale bez debuggeru(muzete pouzit fulscreen fsdb), - kompletni zdrojaky, - MIKMOD - (knihovnu pro mixovani waviku a prehravani modu, s3m, xm a dalsich na sb compatible a GUSovi), - SBlib - (pro sound blaster), - Djp - pro velice ucinou(cca 53%) a rychlou compresi exacu. (decomprese asi 10MB do secundy, takze jsou tim okamzite zabalil celou distribuci) - Emacs - nejlepsi programatorske prostredi s podporou vsim, na co si vspomenete(samozndrejme kompilace, dubugger, barvicky, automaticke formativani zdrojaku pod rukou, upravovani slozitych vyrazu ale treba i piskvorky, kalendar, osobni psichiatr a dalsi dulezite sluzby) - EMU387, WMEMU386 - Dva emulatory koprocesoru - SVGALIB, XLIBEMU - emulaci X oken(moznost poustet jednu X aplikaci primo z dosu...ne X server) pro prevadeni unix software - ZLIB .. - Nepreberne mnostvi sikovnych knihoven jako zlib a lzo pro praci s compresovanymy soubory, databasove knihovny atd.. - CWSDPMI, PMODE - dva kvalitni dpmi servery, ktere muzete sirit z vasi aplikaci a tak vase aplikace uz nebude potrebovat nic jineho z distribuce - TCPLIB - tcp/ip knihovna - podpora dlouhych nazvu ve w95 - mnoho pomocnych programu z unixu v projektu GNUish Naroky na hradware ================== - Alespon 4MB ram(jinak to je sebevrazda) doporuceno 8, nebo 16 - 386SX (doporuceno 486/66) - Hodne(minimalne 5MB) mista na disku - doporuceno 3MB cache ale nesebrat vsechnu pamet cachi! kompiler vyuziva veskerou dostupnou pamet!(ja pouzivam combi) - doporucen RAM disk, ale ja ho nepouzivam a slape pekne. - Odvahu pustit se do neceho noveho A kde to sezenu? ================ Na vsech mirrorech simtelu v adresari gnu/djgpp/v2*. Napriklad ftp://ftp.zcu.cz/pub/simtelnet/gnu/djgpp ftp://ftp.vse.cz/pub/simtelnet/gnu/djgpp ftp://ftp.eunet.cz/pub/simtelnet/gnu/djgpp ftp://ftp.vse.cz/pub/simtel/vendors/djgpp Dalsi utility a software(hlavne v beta verzich) hned v hlavnim stanu ftp.delorie.com (zatim nemirorovane) a take na ftp.oulu.fi se softwarem ke hram. A co potrebuju? =============== Ke spousteni uz zkompilovanych programu `v2/readme.1st' popisuje jak nainstalovat djgpp `v2/faq201b.zip' Tady najdete odpovedi na pripadne problemy `v2misc/csdpmi3b.zip' CWSDPMI, the DJGPP free DPMI server. Jinak vam programmy budou psat "no dpmi server" v pripade, ze nemate spustene windows, nebo qdpmi atd.. Pro psani a kompilaci C programu potrebujete: `v2gnu/bnu252b.zip' Zakladni programy, jako as-assembler, ld-linker atd.. `v2/djdev200.zip' C include soubory, minimalni vyvojarske prostredi, utility specializovane pro djgpp a dokumentace `v2/djtst200.zip' Nekolik prikladu, ktere otestuji vasi instalaci(tohle neni nutne) `v2gnu/gcc272b.zip' GNU C Compiler `v2gnu/txi360b.zip' Info - prohlizec hypertexove dokumentace Pro C++: `v2gnu/gpp272b.zip' kompiler `v2gnu/lgp271b.zip' C++ Include soubory a GNU classes libraries `v2gnu/obc272b.zip' Pro vyvoj objective c programu Dalsi uzitecne utilitky `v2gnu/gdb412b.zip' Radkovy debugger `v2apps/rhideb.zip' Borlandi IDE `v2gnu/flx252b.zip' Flex - Lex-like generator lexikalnich analyzeru. `v2gnu/bsn124b.zip' Bison - Yacc-like generator parseru. `v2gnu/dif271b.zip' GNU Diffutils (diff, cmp, diff3, sdiff) `v2gnu/mak373b.zip' Make - potrebny programek pro kompilaci vetsiny programu `v2gnu/pat21b.zip' Patch-program pro aplikovani patchu(uprav) do zdrojaku `v2gnu/sed118b.zip' Sed-neinteraktivni radkovy davkovy editor. Pokud nevite co to je, vetsina programu je popsana v mych predchozich skolickach na http://www.paru.cas.cz/~hubicka/skolicky Ostatni uzitecne programky ktere nejsou standardni distribuce jsou: (najdete je vetsinou v adresari contrib, nebo na ftp.delorie.com) DJP - uzitecna utilitka, kterou muzete bez obav zabalit vsechny exace a bez straty na rychlosti(spis urychli) usetrit haldy mista na disku ALLEGRO - OPRAVDU dobra knihovna pro psani her ve 256ti barevnych modech. podporuje napriklad: - vsechny mozne mody od 256x200 do 1024x768 - vesa 1.2,2.0,S3,trident a dalsi karty - midi a mixovane wavy na soundblasteru(doporucuji pouzit misto toho mikmod) - uzivatelske prostredi s menu atd.. - double buffering, paging scrolling a moc dalsich vymozenosti - praci se sprite - pakovani vsech dat ze hry do jednoho zabaleneho datoveho souboru - Praci s mysi - Fonty(i vektorove, proporcionalni) fura dalsich veci(uvazuju nad linuxackym portem) MIKMOD - dobry mod player plus knihovna kterou muzete vyuzit ve svych programech. GNUDEBUG - dva celoobrazovkove debuggery JLIB - o nevo horsi knihovna TA2AS - jiz zminovany prevadec .asm souboru Jak optimalne nakonfigurovat MS-DOS =================================== pro 2MB - ZADNY spravce pameti(himem apod) - Pouzivat male CWSDPMI jako DPMI server - Vycistit autoexec a vyndat vsechny zbytecnosti(SETVER,HIMEM apod) - Nepouzivat Cache ani ramdisk ale nastavit BUFFERS na slusnou hodnotu treba BUFFERS=40,8 - Pouzit cwsparam pro nastaveni cwsdpmi a "Minimum application memory desired before 640K paging" nastavit na 512 s tim si muzete hrat a zlepsit vykon celkove se tak malo pameti nedoporuce, gcc musi hodne swapovat a to rychlosti neprida.. a rozhodne nepouzivejte pro 3-4MB - ZADNY spravce pameti(himem apod) - Pouzivat male CWSDPMI jako DPMI server - Vycistit autoexec a vyndat vsechny zbytecnosti(SETVER,HIMEM apod) - Muzete pouzit cache v konvenkcni pameti (256 KB) nebo BUFFERS na slusnou hodnotu treba BUFFERS=40,8. Doporucuju inteli write, protoze hodne pomuze a gnu je celkem stabilni - zadny ramdisk - Pouzit cwsparam pro nastaveni cwsdpmi a "Minimum application memory desired before 640K paging" nastavit na 512 s tim si muzete hrat a zlepsit vykon pro 5-8MB - Pouzivat spravce pameti jako emm386 nebo qemm, pouzit frame=none pro vypnuti ems pameti - Nahrat vsechny DOS ovladace nahoru(devicehigh, lh v autoexecu, nebo pustit optimize u qemm) - Pouzit 1MB cache s write-back - zadny ramdisk - pokud stale mate vic jak 2.5MB volno ( nebo 4MB pro C++) zvetsete cache pro 16MB - Pouzivat spravce pameti jako emm386 nebo qemm, pouzit frame=none pro vypnuti ems pameti - Nahrat vsechny DOS ovladace nahoru(devicehigh, lh v autoexecu, nebo pustit optimize u qemm) - Pouzit 2MB cache s write-back - zadny ramdisk - pokud stale mate vic jak 5MB volno muzete pouzit ramdisk pro tmp soubory Jak to nainstaluju ================== Jednoduse: vsechny hlavni soubory pomoci pkunzip -d rozbalim do jednoho adresare a potom pridate do path cestu k bin adresari a nastavite pomoci set djgpp=(vas adresar)/djgpp.env cestu ke konfiguracnimu souboru. >>>POZOR<<< cesta MUSI byt napsana s normalnima lomitkama (d:/gcc/djgpp.env) Vyeditujete a pripadne i pozmenite soubor djgpp.env Potom si nahrajete dalsi programy jako alegro a muzete zacit kompilovat. DJGPP Specialitky aneb cast pro pokrocile ========================================= Tady bych se rad venoval nekterym specialne djgpp figlum, ktere v jinych prostredich nenajdete. Predpokladam, ze jste uz neco v djgpp udelali a ze mate prehled jak funguje. Je to prece jenom dos a tak nektere veci se tu delaji prinejmensim prapodivne Zavadeni - crt0 =============== Crt0 se linkuje automaticky do kazdeho exace a neni zrovna nejmensi, protoze obsahuje cely extender. Presto se z neho nechaji nektere veci vyhazet. Dela totiz: - Automatickou expanzi vsech parametru (napriklad a*.* se exmanduje do a.exe apod) - Nacita soubor djgpp.env - Zavadi emulator koprocesoru - Zavadi podporu klavesy CTRL+C (ktera ukonci vas program) To zarizuji nektere funkce. Snad nemusim vysvetlovat ze to prinuti linker zaradit a funkce pro praci se souborem apod a to uz neni takovy drobecek. A tak pokud do sveho programu napisete funkce se stejnym jmenem jako v crt0.o muzete je "prepalit" svymy kratsimy, ktere delaji jen to, co je treba(maro ktera konecna plikace vyzaduje djgpp.env soubor a skoro zadna nebere jako parametry soubory) to muzete udelat nasledujicimi funkcemi: void __crt0_load_environment_file(char *_app_name) { return; } /*nenahravat enviroment*/ void __crt0_setup_arguments(void) { return; } /*nezpracovavat parametry*/ char **__crt0_glob_function(char *_arg) { return 0; } /*nezpracovavat "zolinkove" znaky v parametrech*/ Dalsi nedokumentovane funkce umoznuji skratit kod jeste vice: void _npxsetup(void) { return; } int __emu387_load_hook; short __djgpp_ds_alias; void __djgpp_exception_setup(void) { return; } int __djgpp_set_ctrl_c(int enable) { return 0; } (u nekterych je funkce jasna, u jinich ji nevim..je to z programu djgpptsr coz je rezidentik v gnu..moc pekna vecicka) Dalsi dulezita vec je velikost zasobniku. Tu muzete u exace menit pomoci stubedit a nebo ve zdrojacich pomoci int stklen = velikost; Navic crt0 umoznuje definovat flagy pomoci: int _crt0_startup_flags = flag1 | flag2; Kratky soupis flagu: _CRT0_FLAG_PRESERVE_UPPER_CASE jestli argv[0] (nazev programu) ma byt upper nebo lower case _CRT0_FLAG_USE_DOS_SLASHES jestli pouzivat dosacke \ jinak se pouziva unixove / .. toto by se melo zapinat pro nativni dos programy.. _CRT0_FLAG_DROP_EXE_SUFFIX Kdyz je nastaven sunda .exe z konce argv[0] _CRT0_FLAG_DROP_DRIVE_SPECIFIER Kdyz je nastaven odebira c: z argv[0] _CRT0_FLAG_DISALLOW_RESPONSE_FILES Pokud je nastaven neprovadi se nasledujici: @gcc.rf v parametrech zpusobi, ze soubor gcc.rf je nacten a jeho obsah pouzit jako parametry _CRT0_FLAG_FILL_SBRK_MEMORY Celou pamet vynuluje, nez ji zacne pouzivat. Obcas to rozhodi nektere buggy programy _CRT0_FLAG_FILL_DEADBEEF Vyplni pamet konstantou 0xdeadbeef kdyz se vam to objevi v promenych, vite ze je neco spatne _CRT0_FLAG_NEARPTR vytvory 4GB ds limit, ktery umoznuje pouzivani blizkych ukazatelu do dos pameti. To ale zpusobi moznou nestabilitu vaseho programu, protoze neexistuje ochrana pameti _CRT0_FLAG_NULLOK Vypne se ochrana proti pouzivani ukazatele NULL _CRT0_FLAG_NMI_SIGNAL Zapne ovladani NMI signalu. To ale muze delat potize na laptopech a green pocitacich. Jinak se NMI handluje pres realny mod.. _CRT0_FLAG_NO_LFN Vypina podporu dlouhych nazvu ve w95..dobre pro dos aplikace, ktere s tim nepocitaji _CRT0_FLAG_NONMOVE_SBRK(default) _CRT0_FLAG_UNIX_SBRK NONMOVE sbrk pri alokaci noveho bloku pameti(pomoci malloc) pozada dpmi server o novy blok. To ale muze zpusobit to, ze pretece pocet handleru bloku v himem.sys pri allokovani velkeho poctu malych bloku UNIX sbrk proste zvetsi velikost bloku. To je pomalejsi ale nektere aplikace to vyzaduji. Na druhe strane je o nevo pomalejsi a w95 nedovoli takto allokovat vice nez 1/2 pameti..nic neni prefektni _CRT0_FLAG_LOCK_MEMORY Zamkne veskerou pamet(dobre kdyz pouzivate hodne hardwarovych interruptu a malo pameti, jinak je mozne, ze je zrovna vyswapovana a neni) jinak je nutne vsechny funkce a promene zamykat, kdyz jsou pouzivane z interuptu a to muze selhat. k tomu slouzi go32_dpmi_lock_data(ptr,kolik) a go32_dpmi_lock_code pro fce. Jak natvrdo do dosu a na grafiku ================================ Obcas je treba "natvrdo" pristup do dos pameti. nejcastejsi problem je grafika(kdyz nepouzijete zadnou se skvelych grafickych knihoven) Pamet je na A000:0000 ale to v zadnem pripade neplati pro djgpp programy! Je potreba selector. Ten mame k dispozici pomoci _dos_gs v go32.h takze nejjednodussi zapis do vram v assembliku vypada asi takto: short our_global_selector; ... our_global_selector = _dos_ds; ... movw _our_global_selector, %es movl $0xa0000, %edi ;** 0xA000*16 + 0x0000 = 0xA0000 (BTW nevo o AT&T syntaxi assembleru se doctete na me strance http://www.paru.cas.cz/~skolicky ve skolicce o gas) Prepocet je ve formatu segment*16+offset. A takhle vypada putpixel: movw _our_global_selector, %es movl $0xA0000, %edi imulw $320, %ax addw _x, %ax addw %ax, %di movb _color, %al stosb A take: movw _our_global_selector, %fs movl $0xA0000, %ebx ... movb _color, %al movb %al, %fs:(%ebx) A nebo nejjednoduseji: #include #include #include #define putpixel(x,y,c) _farpokeb(_dos_ds, 0xA0000 + (y)*320 + (x), (c)) s optimalizaci bude farpokeb inline a tak nebude ani zadna strata na rychlosti. Kdyz nechceme pokazde nastavovat selector je mozne pouzit: /* circle routine */ ... _farsetsel(_dos_ds) /* loop */ ... _farnspokeb(0xA0000 + y*320 + x, color); ... /* end loop */ _farsetsel(_dos_ds) do fs naladuje a kdyz to nikdo nezmeni, muzete se na to spolehnout. NEARPTR ======= Dalsi moznost je pripojit si dos ke sve pameti. To ale vypne protekci pameti! #include #include #include unsigned char *videoptr = (unsigned char *)0xA0000; __djgpp_nearptr_enable(); videoptr[y*320 + x + __djgpp_conventional_base] = color; __djgpp_nearptr_disable(); POZOR: __djgpp_conventional_base neni konstanta BLOKOVY PRISTUP =============== Asi nejrychlejsi cesta: #include #include #include unsigned char *videoptr = (unsigned char *)0xA0000; unsigned char *doublebuffer = (unsigned char *)malloc(320*200); void copy_buffer(void) { dosmemput(doublebuffer, 320*200, videoptr); } void copy_buffer2(void) { movedata(_my_ds(), doublebuffer, _dos_ds, videoptr, sizeof(*doublebuffer)); } _my_ds() jenom vraci selektor. a jeste: #include #include #include void setmode(short mode) { __dpmi_regs r; r.x.ax = mode; __dpmi_int(0x10,&r); } struct rgbstruct { char red, green, blue; }; void setpalette(char color, struct rgbstruct rgb) { outportb(0x3c8, color); outportb(0x3c9, rgb.red); outportb(0x3c9, rgb.green); outportb(0x3c9, rgb.blue); } Rezident v djgpp ================ Jako raritku jeste prikladam rezidentni program v djgpp. Blika na obrazovce a v pameti zabira 700 byte ale dpmi server 50 :) no ale..ukazuje jak se pracuje s interrupty /* DJGPPTSR, Nov 1995 Charles Sandmann (sandmann@clio.rice.edu) ABSOLULTELY NO WARRANTY. May be redistributed or copied without restriction. An example of a DJGPP TSR. This routine changes the video attribute of the character in the upper right of the screen once per tick (from protected mode). The DPMI provider will be forced to stay resident after this image exits. This code also shows an undocumented way to suppress the exception code loading to decrease the image footprint size. Not optimal - you can do the same thing with a single GAS file with a much smaller image. Left as an exercise for the user. Have fun! */ #include #include #include #include #include #include #include int _stklen = 8192; int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY; void __crt0_load_environment_file(char *_app_name) { return; } void __crt0_setup_arguments(void) { return; } char **__crt0_glob_function(char *_arg) { return 0; } /* Start undocumented way to make exception handling disappear */ void _npxsetup(void) { return; } int __emu387_load_hook; short __djgpp_ds_alias; void __djgpp_exception_setup(void) { return; } int __djgpp_set_ctrl_c(int enable) { return 0; } /* End undocumented way to make exception handling disappear */ void int8(void) { unsigned offset = ScreenPrimary+(2*79)+1; _farsetsel(_dos_ds); _farnspokeb(offset,1+_farnspeekb(offset)); } void main(void) { __dpmi_regs regs; _go32_dpmi_seginfo pmint; pmint.pm_selector = _my_cs(); pmint.pm_offset = (unsigned)&int8; _go32_dpmi_chain_protected_mode_interrupt_vector(8, &pmint); _write(2,"Installing DJGPP TSR\r\n",22); /* __djgpp_exception_toggle(); */ /* Only needed if exceptions linked */ regs.x.ax = 0x3100; regs.x.dx = (256) / 16; /* paragraphs */ __dpmi_int(0x21, ®s); }