home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2MISC / PMODE12B.ZIP / BIN / PMODEDJ.DOC < prev    next >
Encoding:
Text File  |  1997-07-30  |  24.9 KB  |  553 lines

  1. PMODE 3.07 is Copyright (c) 1994, by Tran (a.k.a. Thomas Pytel).
  2. PMODE/DJ modifications are Copyright (c) 1996, by Matthias Grimrath.
  3. PMSTUB.ASM is Copyright (c) 1995, by DJ Delorie, distributed with permission.
  4.  
  5. License Information
  6. -------------------
  7.  
  8. PMODE/DJ is free software.  It may be used or distributed in any manner you
  9. wish, as long as you do not try to sell an extender based on PMODE.  You
  10. may use this software in for profit productions.  If you use this software
  11. in any package, you MUST give credit to Thomas Pytel and Matthias Grimrath.
  12.  
  13. If you use it in for profit productions, you are encouraged to email
  14. the authors of PMODE/DJ.  All others may give feedback, too, of course!
  15.  
  16. PMODE/DJ comes with ABSOLUTELY NO WARRANTY; excluding any and all implied
  17. warranties, including warranties of merchantability and fitness for a
  18. particular purpose.  There is no warranty or representation, either express
  19. or implied, with respect to this code, its quality, performance,
  20. merchantability, or fitness for a particular purpose.  The entire risk
  21. of using this program is with you.  There will be no liability for special,
  22. incidental, or consequential damages arising out of or resulting from the use
  23. or modification of this code.
  24.  
  25.  
  26. What is PMODE/DJ?
  27. -----------------
  28.  
  29. PMODE/DJ is an enhanced version of Tran's PMODE 3.07 for DJGPP.  It provides
  30. DPMI 0.9 services which are needed for a DJGPP image to run under DOS, where
  31. DPMI services usually are not available.  PMODE/DJ was designed for speed and
  32. small size, so it is ideal for demos, games and time critical programs.
  33. PMODE/DJ is an alternative to CWSDPMI which allows an imbedded DPMI provider
  34. in the stub instead of being in a separate image.
  35.  
  36. PMODE/DJ comes in two forms:
  37.  
  38. - A stubonly version (pmodstub.exe) is a stub that can be bound to the
  39.   coff image produced by DJGPP V2's gcc.  No other programs are required
  40.   to run the DJGPP app, you need just the single executable file.
  41.  
  42. - A TSR version.  This is more or less a direct replacement of CWSDPMI,
  43.   which does not require existing images to have the stub replaced.
  44.  
  45. The main porting was done by Matthias Grimrath.  (m.grimrath@tu-bs.de)
  46.  
  47. Thanks must go to:
  48. - Thomas Pytel for writing such excellent code.
  49.  
  50. - Chris Matrakidis (c.matrakidis@eleceng.ucl.ac.uk) who corrected the cpu
  51.   identification, wrote the DPMI functions 0xE00 + 0xE01, improved
  52.   exception handling and FPU emulation.
  53.  
  54. - Charles Sandmann (sandmann@clio.rice.edu) who made the TSR version
  55.   together with Chris Matrakidis and distributed PMODE/DJ.
  56.  
  57. -----------------------------------------------------------------------
  58.  
  59. Files:
  60. ~~~~~~
  61. In pmode12b.zip:
  62.  
  63. PMODSTUB.EXE            Stubonly version
  64. PMODETSR.EXE            TSR version
  65. CRT1.O                  Fixed CRT1.C (only needed for djgpp 2.0)
  66. PMODEDJ.DOC             This file
  67.  
  68. In pmode12s.zip:
  69.  
  70. PMODE.ASM               Kernel of PMODE/DJ 1.2
  71. PMODSTUB.ASM            Stubonly source
  72. PMODETSR.ASM            TSR source
  73. PADSEC.C                Tool to build PMODSTUB.EXE
  74. EHDRFIX.C               Tool to build PMODESTR.EXE
  75. CRT1.C                  Patch for startup code (only needed for djgpp 2.0)
  76. MAKEFILE                Makefile for GNU Make (also requires tasm/tlink)
  77. MAKEFILE.BOR            Makefile for Borland Make (requires tcc/tasm/tlink)
  78.  
  79. -----------------------------------------------------------------------
  80.  
  81. How to use:
  82. ~~~~~~~~~~~
  83.  
  84. - If you want a single executable file, type
  85.     'copy /B pmodstub.exe + a.out prog.exe'
  86.   This assumes 'a.out' is the coff(*) image and 'prog.exe' the name of the
  87.   final executable.  Voila! 'prog.exe' should be fully operational.
  88.  
  89.   Another way would be to copy 'pmodstub.exe' in the same directory of your
  90.   program, possibly renaming it, and change the PMODE/DJ stub to load your
  91.   program - here "myprogram" - by using 'stubedit' and changing the runfile.
  92.   Example: 'stubedit pmodstub.exe -runfile=myprogram'
  93.   Now you can run your program under two names, in this example 'pmodstub'
  94.   and 'myprogram'.
  95.  
  96.   This way you can easily test your program both with PMODE/DJ and with the
  97.   standard stub.
  98.  
  99.  
  100.   (*) Since gcc comes from Un*x, it produces so called coff files, which
  101.       are executable files on some Unices. Obviously DOS is not Un*x, that's
  102.       why each DJGPP produced program has a stub in front of it which DOS can
  103.       execute. The stub itself then executes the coff file.
  104.  
  105.       DJGPP's gcc makes both the plain coff file and a DOS
  106.       executable, unless you specify to omit the coff file.
  107.  
  108.       Example:
  109.       'gcc file1 file2 file3 ... -o prog' creates both 'prog' and
  110.       'prog.exe', where 'prog' is the plain coff file and 'prog.exe' the
  111.       same coff file prepended a DOS stub to it.
  112.  
  113.       'gcc file1 file2 file3 ... -o app.exe' by contrast will only produce
  114.       a stubbed coff file called 'app.exe'. (You may get the plain coff file
  115.       from it by running 'exe2coff' on it)
  116.  
  117.  
  118. - To use the TSR version, copy it into the same directory of your
  119.   program, or somewhere in your path.  Then stubedit your program to change
  120.   the filename of the DPMI provider to PMODETSR.EXE.  For quick testing, run
  121.   PMODETSR.EXE by hand, followed by your program. You can also rename
  122.   PMODETSR.EXE to CWSDPMI.EXE and place it in the same directory as the
  123.   image being executed. The TSR will only stay resident for a single DPMI
  124.   program execution (it's really designed to be dynamically loaded) and is
  125.   not specific to DJGPP (it follows the DPMI 0.9 specification).
  126.  
  127.  
  128. The optimal setup for PMODE/DJ is a plain DOS system, loaded with HIMEM.SYS
  129. or without any memory utility at all. (no EMM386 or other EMS Memory Manager)
  130.  
  131. If you want to compress the stub, you will have to pad the compressed exefile
  132. on a 512 byte boundary.  Otherwise you cannot execute the file, at least not
  133. from other DJGPP programs.  You have to change both the filesize and the
  134. exeheader!
  135.  
  136. Replacing CWSDPMI with PMODETSR for all programs and development is usually
  137. a bad idea, since PMODE/DJ doesn't free allocated resources itself, and it
  138. has some other limitations listed below.  If your program crashes many times,
  139. you may run out of memory.
  140.  
  141. You should also note that PMODE/DJ is a bit incompatible with
  142. DJGPP version 2.0.  Versions 2.01 or higher shouldn't cause trouble.  See
  143. Pitfalls for details.
  144.  
  145. One last word: PMODE/DJ is out for quite a while now, but there was little to
  146. no feedback. We would really like to know if anyone is using this program,
  147. and if so, what experiences you have made. Don't be shy, we won't bite you!
  148.  
  149.  
  150. -----------------------------------------------------------------------
  151.  
  152. Pitfalls in PMODE/DJ:
  153. ~~~~~~~~~~~~~~~~~~~~~
  154.  
  155. Following up are some things to take care of when using PMODE/DJ.  Mostly
  156. they deal with practices allowed by true DPMI hosts but cause PMODE/DJ
  157. to hang.
  158.  
  159. The following list is quite long; however, most programs will run smoothly.
  160. Unless your are doing tricky things you won't run into trouble. As a general
  161. guide, if you don't understand one of the sections below, you may ignore it.
  162. (Because you are probably not doing the things described there)
  163.  
  164. Just try if PMODE/DJ works for you!
  165.  
  166.  
  167. ) PMODE/DJ doesn't offer virtual memory.  For ported Unix/Windows/OS2 or
  168.   other memory consuming apps PMODE/DJ probably is the wrong choice.  But
  169.   it is the right thing for demos and freaky stuff! :=)
  170.  
  171.   Often people think that using PMODE/DJ (or CWSDPR0) makes locking memory(*)
  172.   unnecessary.  THIS IS NOT TRUE!  A user may choose to run your program
  173.   under a DPMI host (Windows for example), which requires memory to be locked
  174.   AND has complete control over the system.  PMODE/DJ has no choice and must
  175.   pass control to that DPMI host, and so your program MUST lock memory!
  176.  
  177.   (*) If you don't know what "locking memory" means and why it must be used,
  178.       please get the latest FAQ (2.02 as of this writing) and read the
  179.       chapters about interrupts and low-level programming.  It's too complex
  180.       to describe here.
  181.  
  182.  
  183. ) The stack registers 'ss:esp' must always contain valid values, or
  184.   interrupts must be disabled.  So if your last-ounce-of-speed-optimized
  185.   assembler routine (mis)uses 'esp' to get another register, disable
  186.   interrupts before.  The 'ceil()' and 'floor()' functions of 'libm.a' have
  187.   a bug and use memory below the stack pointer.  Do not use these functions
  188.   unless you disable interrupts or use CWSDPMI (even then, these functions
  189.   won't work with FPU emulation).(*) The reason is that PMODE/DJ doesn't
  190.   switch stacks on interrupts for speed reasons.  All other DPMI hosts which
  191.   don't run at ring 0 seem to change stacks.
  192.  
  193.   (*) They might be fixed as of this writing
  194.  
  195.  
  196. ) You might consider writing your own versions of malloc/free.
  197.   (Or write your own new/delete operator, if you are talking C++).
  198.   The default functions often allocate much more memory than actually
  199.   needed. Quite ok for systems with virtual memory, but annoying under
  200.   PMODE/DJ.
  201.  
  202.  
  203. ) Avoid allocation of small and many DPMI memory blocks.  DPMI memory
  204.   allocation calls are made with each call to sbrk which itself is
  205.   called by 'malloc()' or 'new' if the current heap is not big enough.
  206.   There's a strict number of memory handles under a XMS system (booted
  207.   only with HIMEM.SYS).  You can get away from this problem if you use
  208.   the unix sbrk algorithm (see <ctr0.h> for details).  However, when you
  209.   use the unix sbrk algorithm the base address of your program may change;
  210.   using 4GB nearpointers gets complicated.  (Nothing is perfect... :( )
  211.  
  212.   This problem only occurs under XMS (aka HIMEM.SYS). Under VCPI or raw
  213.   mode (other types of memory modes PMODE/DJ handles) you can allocate
  214.   as many blocks as fit into the memory.
  215.  
  216.   Newer versions of HIMEM.SYS doesn't seem to have a limited number of
  217.   memory handles.  If you face problems with memory you might try to
  218.   upgrade your HIMEM.SYS.
  219.  
  220.  
  221. ) DJGPP V2.0 startup code is incompatible with the stubonly version.
  222.   If you have V2.01 (or higher) installed you may safely skip this paragraph.
  223.   You may also delete the 'crt1.?' files.
  224.  
  225.   If you still have V2.0 it's a good idea to upgrade to V2.01.  It has fixes
  226.   for many bugs found in V2.0.
  227.  
  228.   In V2.0 the psp address in _go32_info_block is not valid (it's computed
  229.   based on an assumption of the layout of the stub which isn't true).
  230.   Even though you may not use the psp address, it is implicitly
  231.   used by the library function fstat() and routines which may call it.
  232.  
  233.   As a work around, use the TSR version, or relink the image using the
  234.   included CRT1.o which contains a fix for the bug.  You might want to
  235.   insert the fixed CRT1.o into your libc.
  236.  
  237.  
  238. ) One word ahead: The following section smells like a troublemaker, but in
  239.   fact it isn't.  For your information, CWSDPMI is reprogramming the PIC too,
  240.   and CWSDPMI runs well.
  241.  
  242.   PMODE/DJ attempts to reprogram the first interrupt controller to give
  243.   exception handling.  Even though you can use the standard PIC
  244.   mappings for hardware interrupt hooking, you should know that the
  245.   interrupt numbers are mapped internally.  You'll only notice it
  246.   if you try to set a protected mode interrupt that is occupied by the
  247.   reprogrammed PIC (most likely ints from 0x88 to 0x8F).  In such a case
  248.   the setting of such an interrupt will fail.  However, if you specify
  249.   'int $8' directly, PMODE/DJ recognizes it as a software int and passes
  250.   it down to the real mode int handler.
  251.  
  252.   If the master base interrupt controller was reprogrammed before
  253.   PMODE/DJ started, PMODE/DJ will not reprogram it and will report the
  254.   unusual base.  Most programs would fail in this case.  If you want
  255.   to be completely compatible use the following method to set an hardware
  256.   irq:
  257.  
  258.   1. Get master PIC base from
  259.      _go32_info_block.master_interrupt_controller_base, or from DPMI
  260.      function 0x400 directly.
  261.   2. Add the IRQ number (for example 0 = timer, 1 = keyboard).
  262.   3. Use this number to set a real or protected mode interrupt.
  263.   4. Don't forget to unhook interrupts at exit! (Both real and protected)
  264.  
  265.  
  266.   PMODE/DJ hooks real mode hardware interrupts if your program hooks the
  267.   protected mode hardware interrupt. This means your protected mode
  268.   hardware IRQ handler gets called even if the CPU is in real mode.
  269.   However, whenever a hardware interrupt occurs in real mode, each time
  270.   a mode switch happens before your IRQ handler gets called. PMODE/DJ is
  271.   quite fast in mode switching, but if the IRQ's frequency is too high
  272.   (>1kHz), consider installing a bimodal handler (see FAQ for details),
  273.   or make sure your program stays in protected mode all the time.
  274.  
  275.   All other real mode interrupts are not hooked by PMODE/DJ. If you want
  276.   to trap these, use a callback.
  277.  
  278.  
  279. ) Free any extended memory blocks that were allocated.  Unless you don't
  280.   use the DPMI allocation functions directly you needn't care about
  281.   that.  All memory that was allocated through library functions gets
  282.   freed automatically at exit.
  283.  
  284.  
  285. ) Instead of issuing ints directly use the DPMI translation function
  286.   0x300.  In particular, use __dpmi_int() instead of int86() to call real
  287.   mode services (for protected mode services still use int86()).
  288.   Software interrupts are recognized as such, so this is more an advice.
  289.  
  290.  
  291. ) DPMI calls that switch to real mode may clobber the coprocessor.
  292.   This is a problem for assembler code only.
  293.  
  294.  
  295. ) PMODE/DJ checks for the presence of a DPMI host first.  In that case
  296.   your program talks to the DPMI host and not PMODE/DJ.  As discussed above,
  297.   PMODE/DJ doesn't support all DPMI 0.9 features, so if you develop under a
  298.   DPMI host be sure you sometimes test with PMODE/DJ being active!
  299.  
  300.  
  301. ) DOS4GW (tm) doesn't work with PMODETSR.EXE (or CWSDPR0.EXE either).
  302.  
  303.  
  304. ) PMODE/DJ 1.0 has a serious bug.  When using software interrupts,
  305.   the flags are not passed back correctly.
  306.  
  307.   If you have PMODE/DJ 1.0 installed, simply delete it and use this one.
  308.  
  309.  
  310. -----------------------------------------------------------------------
  311.  
  312. Changes from 1.0 to 1.1:
  313. ~~~~~~~~~~~~~~~~~~~~~~~~
  314.  
  315. - software interrupt bug fixed. The flags from realmode haven't been passed
  316.   back correctly. Functions 30xh are not affected.
  317. - Hooking a protected mode hardware interrupt transparently hooks the
  318.   real mode interrupt also. To be compatible with CWSDPMI.
  319. - Function 50Ah removed, because it was dead code.
  320.  
  321.  
  322. Changes from 1.1 to 1.2:
  323. ~~~~~~~~~~~~~~~~~~~~~~~~
  324.  
  325. - numerous bugs fixed that probably will have never showed up.
  326. - functions 0x00E,0x00F (get/set multiple descriptors) turned off.
  327.   These functions won't be used by DJGPP programs.
  328. - callback of int 24 turned off. Since CWSDPMI doesn't callback this
  329.   interrupt, PMODE/DJ needn't support it either. To turn it on you have to
  330.   rebuild PMODE/DJ, setting the appropiate option in the config section of
  331.   PMODE.ASM
  332. - Use of conventional memory as DPMI memory if extended memory is exhausted.
  333. - probably the last release of PMODE/DJ.
  334.  
  335.  
  336. -----------------------------------------------------------------------
  337.  
  338. Differences between PMODE/DJ and the DPMI 0.90 specification:
  339. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  340.  
  341. - descriptors reside in the GDT.
  342. - no allocation of specific LDT descriptors, as descriptor reside in the
  343.   GDT. Function 0x00D was probably only put in for some old dosextenders.
  344. - no debug register support. (functions 0xB00h - 0xB03h)
  345. - Only int 0x23 is callbacked to protected mode. Int 0x1C isn't. If you
  346.   need the timer, hook the hardware irq instead.
  347.   PMODE/DJ handles int 0x24 itself (like CWSDPMI). If you really need it,
  348.   you have to get the sources and change a variable in the config section of
  349.   PMODE.ASM.
  350. - DPMI 1.0 error codes.
  351. - get/set multiple descriptors. (0x00E,0x00F) (turned off by default)
  352. - function 0x801. (free physical address mapping)
  353. - coprocessor functions. (0xE00,0xE01)
  354. - interrupts are off while executing int 31h functions.
  355.  
  356. -----------------------------------------------------------------------
  357.  
  358. Differences between PMODE/DJ and CWSDPMI:
  359. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  360.  
  361. - no virtual memory
  362. - no NULL pointer protection
  363. - no debug support
  364. + faster than CWSDPMI
  365. + smaller than CWSDPMI (in size and consumed DOS memory if not nested)
  366. + comes in a version which can be imbedded in the stub (one image!)
  367. - does not support nesting (new version loaded for each task)
  368.  
  369. ------------------------------------------------------------------------
  370.  
  371. Differences between PMODE/DJ and Tran's PMODE v3.07:
  372. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  373.  
  374. Sad things first:-(
  375. - PMODE/DJ is bigger in size. (about 7K)
  376. - mode switching is a bit slower.
  377. - dos execute call hooked. The interrupt controller must be reset when
  378.   the application shells out.
  379.  
  380. Happy things 2nd:-)
  381. - exception handling with no slowdown to the irq process.
  382. - dos memory allocation.
  383. - physical address mapping. (VBE 2.0!!)
  384. - dynamic allocation of pagetables at startup. You don't need to
  385.   increase the # of pagetables by yourself.
  386. - Use of folds, structs and macros.
  387. - Use of dos memory for DPMI memory.
  388. - A certain protected mode switch type can be forced or forbidden.
  389. - A 16 bit DPMI host is ignored. (No special error code)
  390. - Transparent hooking of real mode hardware interrupts.
  391. - DPMI function 002h added. (Segment to Selector)
  392.   The selector maximum is 16.
  393. - DPMI functions 100h-102h added. (DOS memory services)
  394. - DPMI functions 300h-302h rewritten.
  395. - DPMI function 50Ah removed.
  396. - DPMI functions 600h-603h,70xh added. They only clear the carry as PMODE/DJ
  397.   doesn't support virtual memory. (so far?)
  398. - callback code rewritten.
  399. - DPMI functions 202h-203h added. (Get/Set Exception vectors)
  400.   The standard exceptionhandler will only turn on the PC speaker.
  401. - error code 3 (DPMI host not 32bit) means now that PMODE/DJ has found
  402.   no way to switch into protected mode. Can only happen if some
  403.   switchtypes have been forbidden by the caller.
  404. - When using the raw mode switching routines, keep in mind that they use
  405.   some stack space on both the real mode and protected mode stacks.
  406.   Unlike the original PMODE it is possible now to use the same stack for
  407.   real and protected mode. (The stacks can still be different of course)
  408. - Int 23h and 24h are now callbacked to protected mode. Int 1Ch isn't still.
  409.   I don't see a real reason why.
  410. - Int 0,1,3-15 are all treated as fatal exceptions. (Like CWSDPMI treats
  411.   them). Int 2 (NMI) is passed down to real mode. (It wasn't that easy...)
  412. - returned DPMI version is 0.9.
  413. - Interrupts may be enabled in a callback. The selector in DS is still the
  414.   same for all callbacks, but it is a selector with a fixed base of zero.
  415.  
  416. ------------------------------------------------------------------------
  417.  
  418. Still to do:
  419. ~~~~~~~~~~~~
  420.  
  421. - Int 0x24: If the flags say that fail is not possible, DOS will
  422.   terminate PMODE/DJ which will result in loss of extended memory and
  423.   probably in a system crash. Anyone any idea on how to get rid of this
  424.   problem?
  425. - Int 0x1c: Call back to PM if hooked
  426.  
  427. ------------------------------------------------------------------------
  428.  
  429. Bugs (or strange things) found in PMODE v3.07:
  430. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  431. correct this text if they're not bugs.
  432.  
  433. Bug 1:  VCPI installation check. Some EMS Memory Managers (e.g EMM386
  434.         V5.0) doesn't offer their VCPI interface when no EMS page is
  435.         allocated. Or is it possible then to switch into protected mode
  436.         by XMS?
  437. Bug 2:  Forgot to clear the carry at successful exit at pm_info!
  438. Bug 3:  On entry: If DS = SS, two selectors instead of one are created!
  439. Bug 4:  I am not sure, if the caller can modify or free the initial
  440.         cs, ds, and ss selectors in the original source
  441. Bug 5:  Not sure. At exit with int21, ah=4c, forgot to free the allocated
  442.         memoryblock at startup. Also forgot to restore A20 state.
  443. Bug 6:  When copying stack params in function 300h - 302h, you can see
  444.         'lea esi,[esp+36h-2]'. -2 is wrong, 36h is the correct stack
  445.         offset!
  446. Bug 7:  int31testaccess: code 'test cl,90h; jz... jpo...'
  447.         Is it illegal to clear the present bit of descriptors?
  448.         My DPMI doc says no!
  449. Bug 8:  int31testaccess: the test if codesegments are non-conform and
  450.         readable is wrong. It is possible to create a codesegment that
  451.         is non-conform but not readable!
  452. Bug 9:  After switching to protected mode, forgot to clear the TS bit
  453.         in CR0. This bit is set after a task-switch (the VCPI switch is
  454.         done via a task switch) and thus would cause an exception if a
  455.         program uses the copro!
  456. Bug 10: After raw mode switching to protected mode, forgot to set up
  457.         the taskregister and the local descriptor table. OK, in
  458.         PMODE v3.07 a task switch never happens, but in PMODE/DJ.
  459.         (This is why mode switching is bit slower in PMODE/DJ :(
  460.  
  461. ------------------------------------------------------------------------
  462.  
  463. Minor differences between PMODE/DJ and DPMI:
  464. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  465. (Some lines are copied from Tran's doc of PMODE v3.07. Do you mind, Tran? ;)
  466.  
  467. ) DPMI: IRET(D) and POPF(D) may not affect the interrupt flag. PUSHF(D)
  468.     may not store the interrupt flag.
  469.   PMODE/DJ: IRET(D) and POPF(D) affect the real interrupt flag.
  470.     PUSHF(D) stores the real interrupt flag.
  471.  
  472. ) In protected mode, ESP must always be the stack pointer. Meaning, even if
  473.   using a 16bit stack segment, the high word of ESP MUST be 0.
  474.  
  475. ) When calling the raw mode switching routine to switch into protected mode,
  476.   you must supply the full ESP and EIP. Even if the stack or code segments
  477.   being switched to are 16bit.
  478.  
  479. ) DPMI 1.0 will reload any segment registers for which the descriptor is
  480.   changed through an INT 31h function. PMODE/DJ reloads only ds,es,fs,gs,
  481.   but not ss. Both will zero the segment registers freed with function 0001h.
  482.   DPMI 0.9 may or may not.
  483.  
  484. ) Remember that DPMI 0.9 does not return error codes as DPMI 1.0/PMODE/DJ
  485.   do.
  486.  
  487. ) Under PMODE/DJ, the AVL bit of descriptors is used to keep track of
  488.   free and used descriptors. The value you pass for this bit when
  489.   setting descriptor access rights will be ignored.
  490.  
  491. ) When switching modes using the raw mode switching routines, make sure
  492.   there is some space on both stacks (real and protected). Specific DPMI
  493.   requirements may vary, but 32 bytes is enough for PMODE/DJ.
  494.  
  495. ) Under XMS an extra 15 bytes will be allocated for possible aligning of
  496.   the XMS memory block on a paragraph. Though an XMS block will probably
  497.   already be aligned on at least a paragraph boundary, this is not
  498.   defined in the XMS standard. And to keep the possibility of problems
  499.   at nil, this is done.
  500.  
  501. ) Be aware that memory allocation functions under XMS use real mode
  502.   calls and real mode stack space. If there is not enough stack space
  503.   for the call to the real mode XMS driver, error code 8010h
  504.   (resource unavailable) will be returned.
  505.  
  506. ) If an XMS memory lock fails, which is used in memory allocation
  507.   functions, error 8010h will be returned. A memory lock failure is not
  508.   due to memory not being available. But rather, some internal XMS crap.
  509.   But it should never happen anyway.
  510.  
  511. ) The raw system checks both INT 15h and the VDISK low to high extended
  512.   memory allocation scheme to get its available extended memory area.
  513.  
  514. ) The raw system allocates extended memory on an as-needed basis from
  515.   the top down. INT 15h function 88h is hooked and the total amount of
  516.   memory allocated using the kernel function 0501h is subtracted from
  517.   the amount of memory returned from the previous INT 15h handler. This
  518.   is so that you can execute other protected mode programs from within
  519.   your programs and they will have extended memory available (if you
  520.   left any).
  521.  
  522. ) A protected mode IRQ handler or real mode callback must return on the
  523.   same stack it was called with.
  524.  
  525. ) A real mode routine called with functions 0300h, 0301h, or 0302h must
  526.   return on the same stack it was called with.
  527.  
  528. ) You should make no assumptions about the low memory protected mode
  529.   data area needed by PMODE. It can range from very small to very large.
  530.   And if a DPMI host is present, it is unpredictable.
  531.  
  532. ) Make sure you do not access, read or write, extended memory outside
  533.   the blocks you allocate. Even if there is no physical memory there,
  534.   you will probably get exceptions under DPMI/VCPI.
  535.  
  536. ) When setting descriptor access rights, remember that the B bit of
  537.   stack descriptors determines whether PUSHes and POPs use SP (B=0) or
  538.   ESP (B=1).
  539.  
  540. ) The reserved field between EBP and EBX in the register structure used
  541.   during a callback is used by PMODE to preserve the high word of ESP
  542.   for real mode.
  543.  
  544. ) You should assume the INT 31h extended memory functions to be slow.
  545.   Especially under VCPI, where a call has to be made to the VCPI server
  546.   for each 4k of memory allocated or freed, and two calls for each 4k
  547.   verified.
  548.  
  549. ) Under PMODE/DJ, software INT redirection calls only pass back the
  550.   carry, parity, aux, zero, sign, and overflow flags from the real mode
  551.   interrupt handler.
  552.  
  553.