Přístup k fyzické paměti -=-=-=-=-=-=-=-=-=-=-=-=-= "Virtual" means never knowing where your next byte is coming from. Pokud potřebujete přístup k nějaké fyzické paměti (třeba videoram), není nic jednoduššího, než požádat DPMI, aby ji dalo do adresovatelného prostoru Vašeho programu. Naneštěstí toto je funkce DPMI 1.0 a vyšší a tak ji hodně DPMI serverů nepodporuje. Proto musí začít magie. I v protected módu existují segmenty a offsety. Segmenty jsou tak velké (celá adresovatelná paměť), že se používá jenom jeden segment. V DPMI ale program běží uvnitř jednoho segmentu, zatímco fyzická paměť je v jiném segmentu. Proto lze použít segmentace pro přístup do vnější paměti. Segment dosu je uložen v proměne _dos_ds a existuje funkce _farpoke* a _farpeek* které umožňují přistupovat na tyto vzdálené ukazatele (_farpokeb přistupuje k bajtu, _farpokel k wordu atd.): extern __inline__ void _farpokeb(unsigned short selector, unsigned long offset, unsigned char value) { __asm__ __volatile__ ("movw %w0,%%fs\n" " .byte 0x64 \n" " movb %b1,(%k2)" : : "rm" (selector), "qi" (value), "r" (offset)); } extern __inline__ void _farpokew(unsigned short selector, unsigned long offset, unsigned short value) { __asm__ __volatile__ ("movw %w0,%%fs \n" " .byte 0x64 \n" " movw %w1,(%k2)" : : "rm" (selector), "ri" (value), "r" (offset)); } Těch lze použít pro adresaci videoram asi takto: #include <go32.h> #include <dpmi.h> #include <sys/farptr.h> #define putpixel(x,y,c) _farpokeb(_dos_ds, 0xA0000 + (y)*320 + (x), (c)) To sice funguje, ale zbytečně se pokaždé nastavuje fs. Jednodušší je ho nastavit jednou na začátku. K tomu slouží funkce _farsetsel a _farnspoke*. Na začátek vykresolvací smyčky dáte: _farsetsel(_dos_ds) a potom kreslíte pomocí _farnspokeb(0xA0000 + y*320 + x, color); Toto je asi nejčastěji používaná metoda pro přístup k paměti. Funguje pod každým DPMI a je docela rychlá. Existují také far verze pro kopírování paměti, takže když neco nakreslíte do framebufferu, neni probém to potom zkopírovat do VRAM. To lze také dělat hned dvěma způsoby: dosmemput(doublebuffer, 320*200, videoptr); movedata(_my_ds(), doublebuffer, _dos_ds, videoptr, sizeof(*doublebuffer)) Další metoda je zpřístupnění celé dosové paměti. To naprosto vypne veškerou ochranu paměti a proto se to nedoporučuje. Pokud ale potřebujete opravdu rychle no RAM, je to jedna z možností. Vypadá to asi takto: #include <go32.h> #include <dpmi.h> #include <sys/nearptr.h> unsigned char *videoptr = (unsigned char *)0xA0000; __djgpp_nearptr_enable(); videoptr[y*320 + x + __djgpp_conventional_base] = color; __djgpp_nearptr_disable(); Je ještě nutné si pamatovat, že __djgpp_conventional_base je proměná a může se měnit po každém zavolání alokace paměti. výheň