Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Blinker 5.10 Online Reference - <b> special considerations for dual mode code</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Special considerations for dual mode code
------------------------------------------------------------------------------
 This section details the suggested way to adapt code to run in both real and
 protected mode, rather than coding specifically for one or the other.

 When linking DOS extended or dual mode programs it is always necessary to
 include an additional Blinker library for the appropriate compiler. This
 library contains replacement .OBJs for any compiler library .OBJs which are
 not protected mode compatible.

 The Blinker libraries all have names of the form BLXcccnn, where ccc
 indicates the vendor and compiler, and nn indicates the compiler version
 number. They are all compiled as large model and so should only be used with
 large model programs. See the section `Linking for protected mode' later in
 this chapter for more details.

 As stated before, most code will actually run in both modes without
 modification. Most of the remaining code will run in either mode after being
 modified to use a variable set up with the appropriate value at start up.
 For example, in the case of directly accessing the video buffer, in C we
 would write:

 #include <stdio.h>
 #include <blx286.h>

 BYTE ProcMode;
 static SEL Selector;
 static unsigned char far *VideoBuffer;
 if (DosGetMachineMode(&ProcMode) == 0)
    switch (ProcMode)
       {
       case 0:
          printf ("\nReal mode - absolute pointers ok\n");
          VideoBuffer = MK_FP(0xb800,0);
          break;
       case 1:
          printf ("\n286 Protected mode - plenty memory\n");
          if (DosMapRealSeg (0xb800, 4000l, &Selector))
             {
             printf ("\nTrouble\n");
             exit (1);
             }
          VideoBuffer = MK_FP(Selector,0);
          break;
       default:
          printf ("\nOther mode - interesting\n");
          exit(1);
       }

 Then:

 *VideoBuffer[0] = `*';     /* Display a `*' in top left

 corner of screen*/

 As can be seen, there is no extra overhead in code or execution speed once
 the initialisation has been done.

 In the exceptional case where the code is totally different for the two
 modes, one of two approaches can be used. The first is to use a simple `if'
 or `switch' statement on a global variable, as is used in the example above
 for the initialisation code. If the choice has to be made throughout your
 code, the second method of using a function pointer is more appropriate.

 #include <stdio.h>
 #include <blx286.h>

 int (*DoCode) (int); /* Variable for function pointer*/
 int ProtCode (int);  /* Protected mode code function */
 int RealCode (int);  /* Real mode code function */

 if (ProcMode)        /* If protected mode */
    DoCode = ProtCode;
 else                 /* Real mode */
    DoCode = RealCode;
 .....
 int ProtCode (int abc)
 {
    printf ("ProtCode %d\n", abc);
    return (abc * 2);
 }
 .....

 Then:

 DoCode(1234);        /* Execute the appropriate code */

 It should be noted that in the unusual cases where an overhead is necessary,
 it is absolutely minimal, less than a millionth of a second in C even on a
 286. In the case of a higher level language such as CA-Clipper, which
 executes hundreds of these tests for each `if' clause in the CA-Clipper
 source, the relative overhead is so small as to be totally irrelevant.
 There is acommon misconception that this type of construct will slow down
 a progrm written in a high level language program such as CA-Clipper.

 However, as tracing such constructs under an assembly language debugger will
 show, even passing a simple logical or integer variable from CA-Clipper to C
 or ASM requires hundreds of CPU instructions, including a large number of
 test and jump instructions like the one above.

 The only time that the overhead is even vaguely an issue is when the code is
 executed hundreds of thousands of times without interacting with, i.e.
 calling or returning to, the high level language.

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson