home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1993 May / SIMTEL_0593.ISO / msdos / turbopas / toad_iac.pas < prev    next >
Pascal/Delphi Source File  |  1988-12-17  |  6KB  |  153 lines

  1. program IAC;
  2.  
  3. (*
  4. This program fiddles with the Inter-Application Communications Area (IAC).
  5.  
  6. The IAC is 16 bytes beginning at addr 0040:00F0h. Any program can
  7. write information to the IAC for another program to read. Please
  8. note: unless the first program directly invokes the second program,
  9. it cannot protect the IAC from being altered by an intervening program.
  10. The IAC can be used, for instance, to pass an address from one program
  11. to the next.
  12.  
  13. People have asked me about rules/guidelines for using the IAC.
  14. There appear to be none!  First come, first served!  DOS doesn't seem
  15. to use it at all (nor any of the common DOS utility programs, so far
  16. as I can tell).  No telling WHAT other programs might depend on the IAC
  17. being undisturbed.
  18.  
  19. How can it be used?  Following are some examples .. take your choice.
  20. Remember, the main reason for its existence is for inter-program
  21. communications .. so don't waste it as a 16-byte buffer!  That's what
  22. you have your data segment for!
  23.  
  24. This code is written in, and works with, Turbo Pascal v3.1.
  25. Donno about v4.0 and up!
  26.  
  27. David Kirschbaum
  28. Toad Hall
  29. kirsch@braggvax.ARPA
  30.  
  31. *)
  32.  
  33. TYPE                                     {Define the IAC in different ways}
  34.   IAC_Array    = ARRAY[0..15] OF BYTE;
  35.   IAC_Str      = STRING[15];             {Length byte + 15 chars}
  36.   Real2_Array  = ARRAY[1..2] OF REAL;    {Reals are 6 bytes, so there's
  37.                                           room for two of them}
  38.  
  39. VAR                                        {Some IAC typed variables}
  40.   iacArrayPtr : ^IAC_Array;                {A pointer to an array of bytes}
  41.   IACStrPtr   : ^IAC_Str;                  {.. and to a string}
  42.   iacRealPtr  : ^Real2_Array;              {.. and to an array of reals}
  43.  
  44.   IAC         : IAC_Array Absolute $0040:$00F0;  {Here is the actual IAC}
  45.   IACMsg      : IAC_Str Absolute IAC;      {Type a string to the same place}
  46.   IACReal2    : Real2_Array Absolute IAC;  {And some reals}
  47.  
  48.   {some program variables to play with}
  49.  
  50.   i       : INTEGER;                     {handy counter}
  51.   S       : STRING[255];                 {a string}
  52.   saveIAC : IAC_Array;                   {an array of bytes}
  53.   r2      : Real2_Array;                 {some reals}
  54.  
  55. BEGIN
  56.   saveIAC := IAC;                        {Preserve the true IAC as an array}
  57.  
  58.   {Play with the IAC with our pointer variable}
  59.  
  60.   iacArrayPtr := Ptr($0040,$00F0);            {Point our pointer to the IAC}
  61.   IACStrPtr   := Ptr($0040,$00F0);            {same place}
  62.   iacRealPtr  := Ptr($0040,$00F0);            {same place}
  63.  
  64.   Writeln('Original IAC bytes: ':20);
  65.   FOR i := 0 TO 15 DO
  66.     Write(IAC[i]:4);                          {write actual IAC bytes}
  67.   Writeln;
  68.  
  69.   Writeln('Using pointer:');
  70.   FOR i := 0 TO 15 DO
  71.     Write(iacArrayPtr^[i]:4);                 {same bytes, using our pointer}
  72.   Writeln;
  73.  
  74.   FOR i := 0 TO 15 DO
  75.     iacArrayPtr^[i] := i;                     {Change it}
  76.  
  77.   Writeln('Changed IAC bytes: ':20);
  78.   FOR i := 0 TO 15 DO
  79.     Write(iacArrayPtr^[i]:4);                 {Read it again}
  80.   Writeln;
  81.  
  82.  
  83.   {Now play with some real numbers}
  84.  
  85.   FOR i := 1 TO 2 DO
  86.     IACReal2[i] := i /3.0;               {Produce some reals in the IAC}
  87.  
  88.   Write('New IAC reals: ':20);
  89.   FOR i := 1 TO 2 DO
  90.     Write(IACReal2[i]:6:3);              {Display the IAC reals}
  91.   Writeln;
  92.  
  93.   Write('Using pointer: ':20);
  94.   FOR i := 1 TO 2 DO
  95.     Write(iacRealPtr^[i]:6:3);           {Display the IAC reals}
  96.   Writeln;
  97.  
  98.   FOR i := 1 TO 2 DO
  99.     r2[i] := i /6.0;                     {Build a local array of reals}
  100.  
  101.   Write('New local reals: ':20);
  102.   FOR i := 1 TO 2 DO
  103.     Write(r2[i]:6:3);                    {Display the local reals}
  104.   Writeln;
  105.  
  106.   IACReal2 := r2;                        {Move the array into the IAC}
  107.  
  108.   Write('Changed IAC reals: ':20);
  109.   FOR i := 1 TO 2 DO
  110.     Write(IACReal2[i]:6:3);              {Display the IAC reals}
  111.   Writeln;
  112.  
  113.  
  114.   IAC := saveIAC;                        {Restore the old IAC}
  115.  
  116.   {Play with the IAC as a Pascal string}
  117.  
  118.   Write('Old IAC as strng: ':20);
  119.   Writeln('[', IACMsg, ']');             {Normally the IAC is empty (0's),
  120.                                           so the first time we run this
  121.                                           program, the string should be
  122.                                           empty (that 0 length byte).
  123.                                          }
  124.   IACMsg := '123456789ABCDEF';           {Change the IAC to our message.
  125.                                           15 chars, right?}
  126.   Write('Changed IAC msg: ':20);
  127.   Writeln('[', IACMsg, ']');             {Now let's display the IAC itself}
  128.  
  129.   Write('Using pointer: ':20);
  130.   Writeln('[', IACStrPtr^,']');
  131.  
  132.   S := IACMsg;                           {Bring the IAC into a local string}
  133.   Write('IAC to local strng: ':20);
  134.   Writeln('[', S, ']');                  {Write the local string}
  135.  
  136.   S := 'HowNowBrownCow?......';          {New msg.  Sure, this string is longer
  137.                                           than the IAC, but since we've typed
  138.                                           the IAC as a 15-char string, Turbo
  139.                                           will only copy 15 characters of THIS
  140.                                           string to it!  No problem over-
  141.                                           running the IAC boundaries and
  142.                                           trashing DOS's data.
  143.                                           }
  144.   IACMsg := S;                           {Leave msg in IAC}
  145.   Write('Local strng to IAC: ':20);
  146.   Writeln('[', IACMsg, ']');             {Let's display the IAC again}
  147.  
  148.   {Now run this program again!  You'll see the message from last time!
  149.    (Which is the whole idea, after all!
  150.   }
  151.  
  152. END.
  153.