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ň