Mail Archives: djgpp/1996/07/16/22:00:19
olly AT mantis DOT co DOT uk (Olly Betts) wrote:
>In article <31eb1f83 DOT sandmann AT clio DOT rice DOT edu>, Charles Sandmann wrote:
>You've said PMODE/DJ is small and fast. What advantages does CWSDPMI offer?
>Does it have fuller DPMI support, and if so, when are the extra features
>useful?
Heres a clipping from PMODEDJ.DOC:
Following up are some things to take care of when using PMODE/DJ.
Mostly
they deal with practices allowed by true DPMI hosts but cause PMODE/DJ
to hang.
) Current DJGPP startup code is incompatible with the stubonly
version.
The psp address in _go32_info_block is not valid (it's computed
based
on an assumption of the layout of the stub which isn't true).
Even though you may not use the psp address, it is implicitly
used by the library function fstat() and routines which may call it.
As a work around, use the TSR version, or relink the image using the
included CRT1.o which contains a fix for the bug. You might want to
insert the fixed CRT1.o into your libc.
) PMODE/DJ attempts to reprogram the first interrupt controller to
give
exception handling. Even though you can use the standard PIC
mappings for hardware interrupt hooking, you should know that the
interrupt numbers are mapped internally. You'll only notice it
if you try to set a protected mode interrupt that is occupied by the
reprogrammed PIC (most likely ints from 0x88 to 0x8F). In such a
case
the setting of such an interrupt will fail. However, if you specify
'int $8' directly, PMODE/DJ recognizes it as a software int and
passes
it down to the real mode int handler.
If the master base interrupt controller was reprogrammed before
PMODE/DJ started, PMODE/DJ will not reprogram it and will report the
unusual base. Most programs would fail in this case. If you want
to be completely compatible use the following method to set an
hardware irq:
1. Get master PIC base from
_go32_info_block.master_interrupt_controller_base, or from DPMI
function 0x400 directly.
2. Add the IRQ number (for example 0 = timer, 1 = keyboard).
3. Use this number to set a real or protected mode interrupt.
4. Don't forget to unhook interrupts at exit! (Both real and
protected)
) PMODE/DJ doesn't hook real mode interrupts. If an interrupt occurs
in
real mode, your program won't get it unless you use a callback.
Especially ctrl-c trapping doesn't work if the processor is in real
mode. This could change in future, as PMODE/DJ reports INT 23 to
your protected mode app. The current version of DJGPP doesn't
support
this, but checks ctrl-c inside the keyboard interrupt directly. :-(
) The stack registers 'ss:esp' must always contain valid values, or
interrupts must be disabled. So if your
last-ounce-of-speed-optimized
assembler routine (mis)uses 'esp' to get another register, disable
interrupts before. The 'ceil()' and 'floor()' functions of 'libm.a'
have a bug and use memory below the stack pointer. Do not use these
functions unless you disable interrupts or use CWSDPMI (even then,
these functions won't work with FPU emulation). The reason is that
PMODE/DJ doesn't switch stacks on interrupts for speed reasons.
All other DPMI hosts which don't run at ring 0 seem to change
stacks.
) Avoid allocation of small and many DPMI memory blocks. DPMI memory
allocation calls are made with each call to sbrk which itself is
called by 'malloc()' or 'new' if the current heap is not big enough.
There's a strict number of memory handles under a XMS system (booted
only with HIMEM.SYS). You can get away from this problem if you use
the unix sbrk algorithm (see <ctr0.h> for details). However, when
you
use the unix sbrk algorithm the base address of your program may
change;
using 4GB nearpointers gets complicated. (Nothing is perfect... :(
)
) Free any extended memory blocks that were allocated. Unless you
don't
use the DPMI allocation functions directly you needn't care about
that. All memory that was allocated through library functions gets
freed automatically at exit.
) PMODE/DJ runs the application in extended memory only. Conventional
memory is not used for DPMI memory. (so far, may change in future)
) Instead of issuing ints directly use the DPMI translation function
0x300. In particular, use __dpmi_int() instead of int86() to call
real
mode services (for protected mode services still use int86()).
Software interrupts are recognized as such, so this is more an
advice.
) DPMI calls that switch to real mode may clobber the coprocessor.
This is a problem for assembler code only.
) PMODE/DJ checks for the presence of a DPMI host first. In that case
your program talks to the DPMI host and not PMODE/DJ. As discussed
above,
PMODE/DJ doesn't support all DPMI 0.9 features, so if you develop
under a
DPMI host be sure you sometimes test with PMODE/DJ being active!
) DOS4GW (tm) doesn't work with PMODETSR.EXE (or CWSDPR0.EXE either).
) PMODE/DJ doesn't offer virtual memory. For ported Unix/Windows/OS2
or
other memory consuming apps PMODE/DJ probably is the wrong choice.
But
it is the right thing for demos and freaky stuff! :=)
-----------------------------------------------------------------------
Differences between PMODE/DJ and the DPMI 0.90 specification:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- descriptors reside in the GDT.
- no allocation of specific LDT descriptors, as descriptor reside in
the
GDT. Function 0x00D was probably only put in for some old
dosextenders.
- no debug register support. (functions 0xB00h - 0xB03h)
- Only int 0x23 and 0x24 are callbacked to protected mode. Int 0x1C
isn't. If you need the timer, hook the hardware irq instead.
- DPMI 1.0 error codes.
- get/set multiple descriptors. (0x00E,0x00F)
- function 0x50A. (Get memory block size and base)
- function 0x801. (free physical address mapping)
- coprocessor functions. (0xE00,0xE01)
- interrupts are off while executing int 31h functions.
- real mode hardware interrupts are not reflected to protected mode.
-----------------------------------------------------------------------
Differences between PMODE/DJ and CWSDPMI:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- no virtual memory
- no NULL pointer protection
- no automatic hooking of real mode ints
- no debug support
- faster than CWSDPMI
- smaller than CWSDPMI (in size and consumed DOS memory)
- comes in a version which can be imbedded in the stub (one image!)
- does not support nesting (new version loaded for each task)
- Raw text -