Why not? Protected Mode was designed by Intel to deal with the inadequacies
of the 16-bit segemented architecture, mainly, the 1MB limit. Apparently
640KB wasn't enough for Bill Gates (Windows 95 runs very slowly on
only 8MB of RAM), so why should it be enough for us? For those of you with
BP7.0, you will understand this. Going from 640KB to 16MB of memory is a
wonderful step.
Speed Considerations
Contrary to popular belief, Protected Mode is not faster than
Real Mode. Loading segment registers is painfully slow, and some of
the instructions are slower in PM (due to the protection mechanism and
privilege level verification). Is this enough of a reason not to use
Protected Mode? Of course not. Balance the ability to have 16MB of
memory immediately accessable versus having to swap it in and out using XMS
or EMS. Obviously PM wins out in this case.
16-bit Segmentation
So you think segmentation is evil? Well, consider this: You've been writing
a game in Borland Pascal that directly accesses the screen. You load up
ES with SegA000, load DI with your offset. You can directly access all
of a Mode 13h screen with just DI. You know where screen memory is; you
know how to access it. Now you decide to switch to Watcom C, which touts a
powerful 32bit DOS extender. Quick, is EDI loaded with 0a000h, 0a00h, or
0a0000h? Okay, that took you four seconds to figure out. Now implement
a keyboard handler that grabs interrupt 9 and dumps keys into a buffer
you have allocated. Is that code going to run in a 32-bit segment or a
16-bit segment? Is that buffer accessable from Real Mode? Well, with
Borland Pascal it is simple to redirect an interrupt, since the compiler
knows that you are running in 16-bit PM (or RM). The Interrupt vector is
readily available for you to do with as you please, and that buffer is
located within the data segment. You've gotten used to 16-bit programming,
segmentation, et al. Use this to your advantage.
Why Borland Pascal 7.0? Why not Delphi?
I'll answer the second question first. Do *you* want to perpetuate a curse
that has been forced upon the naive consumer, namely Windoze? Borland Pascal
is a DOS program; Delphi runs only under Windows. DOS may have flaws, but it
is a comfortable programming platform with little (no?) intrusion from
the OS. Borland Pascal is a wonderful programming environment with a
blindingly fast compiler that only has a few drawbacks. One of these
drawbacks is the 64KB limit. However, Borland accidently produced the
perfect compiler. In Protected Mode each segment has a limit. By default
that limit is 64KB (due to the fact that BP7.0 cannot do 32-bit addressing).
If you allocate 256KB of memory, BP automatically allocates multiple
contiguous 64KB segments. Why is this great? Because if you allocate memory
[using a function such as GlobalAlloc] BP returns a THandle. A Thandle is the
16-bit selector of the memory (ie, load ES with the THandle, and use DI as
the offset). The offset always starts at 0. This is useful because you can
change the selector limit from 64KB to 4GB (gigabytes). With a little inline
assembly you can use ES:[EDI] to access the memory. Yes, that is a 48-bit
pointer, 16-bit selector, 32-bit offset. How many of your friends that use
C can allocate multiple 4-gigabyte pointers? Not many, I presume. Make sure
you gloat, especially to the ones that tried to convert you to C. How to
implement and use 48-bit pointers is discussed in more detail later.
Disadvantages
Protected Mode is a little more difficult to program for. You will take
a speed hit from accessing segment registers. You will also take a one
cycle penalty for each 32-bit instruction you use (because you are running
in a 16-bit code segment). Your code may stop looking like clean code and
more of a mess. Here is a sample piece of code from my Zelda scrolling
engine:
for ty:=0 to 10 do
for tx:=0 to 15 do
PlayingField^.Putimage(tx*SprWidth,ty*SprHeight,ptr48(MapSprites,SprSize*
ReadMem32b(ptr48(Map,longint(RealY+ty)*MapWidth+(RealX+tx)))));
(Please don't comment on how I could optimize this piece of code... I am well
aware that the indexing could be done more efficiently outside of the
procedure call. It is for example purposes only.).