home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / QCOM.ZIP / COMBAR.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-08-23  |  10.3 KB  |  334 lines

  1. { Copyright (C) 1989 by Alpac Systems
  2.                         Finn J. R. Nielsen
  3.                         1741 W. Orchid Lane
  4.                         Phoenix, AZ 85021 }
  5. Program ComBar; uses QCom, Crt, Dos;
  6.  
  7. Const
  8.   minSize = 256;          { Limits for various size queues }
  9.   medSize = 3000;
  10.   maxSize = 6000;
  11.  
  12.   Full_block = 219;       { graphics character values }
  13.   Low_block = 221;
  14.   Esc = 27;
  15.   Cr = 13;
  16.  
  17.   baud_labels: array[ord(B110)..ord(B38400)] of word =
  18.                (110,150,300,600,1200,2400,4800,9600,19200,38400);
  19.   protocol_labels: array[ord(XoffProtocol)..ord(DsrProtocol)] of string[13] =
  20.                    ('Xoff Protocol','Dsr Protocol ');
  21.  
  22. Var
  23.   Comm1, Comm2: ^CommPort;
  24.   Config: commConfig;
  25.   testBaud: BaudRates;
  26.   testProtocol: ProtocolType;
  27.   done, completely_done: boolean;
  28.   origVideo: byte;
  29.   msgLimit, inLimit, outLimit: word;
  30.   inCurMsgNo, outCurMsgNo, inErr: word;
  31.   curQ1, curQ2: word;
  32.   ch: char;
  33.   testStart: longint;
  34.  
  35. { Get a time stamp with resolution to nearest second for elapsed time
  36.   calculations }
  37. Function timeStamp: longint;
  38. Var
  39.   hour, min, sec, hund: word;
  40. Begin
  41.   GetTime(hour,min,sec,hund);
  42.   if hund > 50 then inc(sec);
  43.   timeStamp := sec + min*60 + hour*3600;
  44. End;
  45.  
  46. { Display a text string at specified screen coordinates }
  47. Procedure Display(X,Y: integer; msg: string255);
  48. Begin
  49.   GotoXY(X,Y);
  50.   Write(msg);
  51. End;
  52.  
  53. { Show a status message in upper right corner of screen - update elapsed
  54.   time display }
  55. Procedure Status(statColor: byte; Msg: string255);
  56. Var
  57.   oldAttr: byte;
  58.  
  59. Begin
  60.   oldAttr := textAttr;
  61.   gotoXY(68,2);
  62.   textBackground(statColor);
  63.   textColor(White);
  64.   highVideo;
  65.   write(Msg);
  66.   textAttr := oldAttr;
  67.   gotoXY(35,16); write(timeStamp - testStart,'  ');
  68. End;
  69.  
  70. { Produce a bar graph, which approximates the occupancy rate of a
  71.   specified queue. In this case, the display is VERY "approximate".}
  72. Procedure UpdGraf(Var prevVal: word; Y, qCount, qSize: word);
  73. Var
  74.   oldAttr: byte;
  75.   longTemp: longInt;
  76.   bar_ch: char;
  77.   newInc, newQ: integer;
  78.   ix: word;
  79.  
  80. Begin
  81.   oldAttr := textAttr;
  82.   textBackground(Black);
  83.   textColor(Red);
  84.   longTemp := qCount * longint(150);
  85.   newQ := longTemp div qSize;
  86.   newInc := newQ - ((prevVal shr 1) shl 1);
  87.   bar_ch := char(Full_block);
  88.   if newInc > 0 then gotoXY(4+(prevval shr 1),Y)
  89.   else
  90.   begin
  91.     bar_ch := char(Low_block);
  92.     textColor(Green);
  93.     gotoXY(4+(newQ shr 1),Y);
  94.     write(bar_ch);
  95.   end;
  96.   if (newInc shr 1) <> 0 then
  97.     for ix := 0 to (abs(newInc) shr 1) do write(bar_ch);
  98.   if (newInc mod 2) <> 0 then write(bar_ch);
  99.   textAttr := oldAttr;
  100.   prevVal := newQ;
  101. End;
  102.  
  103. Procedure UpdQueueGraf;
  104. Begin
  105.   UpdGraf(curQ1,11,Comm1^.oCount,Comm1^.oSize);
  106.   UpdGraf(curQ2,14,Comm2^.iCount,Comm2^.iSize);
  107. End;
  108.  
  109. Procedure FinishScreen;
  110. Begin
  111.   Status(Black,'Finished ...');
  112.   textAttr := origVideo;
  113.   gotoXY(1,23);
  114. End;
  115.  
  116. { Initialize the test screen }
  117. Procedure InitScreen;
  118. Begin
  119.   clrScr;
  120.   origVideo := textAttr;
  121.   textAttr := 7;
  122.   highVideo;
  123.   display(4,3,'Turnaround Cable Test (COM1: and COM2:)');
  124.   lowVideo;
  125.   textColor(Cyan);
  126.   display(4,18,'Protocol:');
  127.   display(40,18,'Baud rate:');
  128.   display(4,22,'(Press any key for next test, <esc> to exit)');
  129.   display(4,5,'Writing COM1: until >       bytes in output queue');
  130.   display(4,6,'Reading COM2: until <      bytes in input queue');
  131.   display(4,8,'Input msg:');
  132.   display(4,10,'COM1: output queue (6,000 bytes):');
  133.   display(4,13,'COM2: input queue (3,000 bytes):');
  134.   display(4,16,'Elapsed seconds for this test:');
  135.   textColor(Blue);
  136.   display(4,20,
  137.   'Program material Copyright (C) 1989 by Alpac Systems and Finn J. Nielsen');
  138.   textAttr := 7;
  139.   inErr := 0;
  140.   curQ1 := 0;
  141.   curQ2 := 0;
  142. End;
  143.  
  144. { Initialize the comm ports to default configurations }
  145. Procedure InitPorts;
  146. Begin
  147.   Comm1 := Connect(1,minSize,maxSize);
  148.   Comm2 := Connect(2,medSize,minSize);
  149.   Config := DeflCfg;
  150. End;
  151.  
  152. { Assign random values to queue char limits }
  153. Procedure ChooseParams;
  154. Begin
  155.   inLimit := random(medSize div 2);
  156.   gotoXY(26,6); write(inLimit:4);
  157.   outLimit := random(maxSize * 3 div 4);
  158.   gotoXY(26,5); write(outLimit:5);
  159. End;
  160.  
  161. { Generate some output messages. Stop when the output queue fills beyond
  162.   the limit specified in "outLimit" variable }
  163. Procedure FillOutQ;
  164. Var
  165.   outMsg: string255;
  166.  
  167. Begin
  168.   Status(Red,'Writing ... ');
  169.   while (Comm1^.oCount < outLimit) and (not keypressed) do
  170.   begin
  171.     inc(outCurMsgNo);
  172.     str(outCurMsgNo:6,outMsg);
  173.     outMsg := 'Test message (34 bytes) no:'+outMsg+#13;
  174.     PutString(Comm1,outMsg);
  175.     updQueueGraf;
  176.   end;
  177. End;
  178.  
  179. { Idle routine - waits for some data to be received in the input queue.
  180.   If the transmitter doesn't have anything to send, then idle is also
  181.   terminated. }
  182. Procedure Idle;
  183. Begin
  184.   Status(Cyan,'Idling ...  ');
  185.   repeat
  186.     updQueueGraf;
  187.   until
  188.     ((Comm1^.CommFlags and XmitOn) = 0) or
  189.     (Comm1^.oCount = 0) or
  190.     keypressed;
  191. End;
  192.  
  193. { Read input messages until the input queue has fewer characters left than
  194.   specified by "inLimit" variable.}
  195. Procedure GetMessages;
  196. Var
  197.   inMsg, tempMsg: string255;
  198.   convNo, convCode: word;
  199.   oldVideo: byte;
  200.  
  201. Begin
  202.   Status(Green,'Reading ... ');
  203.   while (Comm2^.iCount > inLimit) and not keypressed do
  204.   begin
  205.     inc(inCurMsgNo);
  206.     inMsg := GetString(Comm2,nil);
  207.     tempMsg := copy(inMsg,28,6);
  208.     val(tempMsg,convNo,convCode);
  209.     tempMsg := copy(inMsg,1,27);
  210.     if (length(inMsg) <> 34) or    { check input message integrity }
  211.        (convCode <> 0) or
  212.        (inMsg[34] <> #13) or
  213.        (convNo <> inCurMsgNo) or
  214.        (tempMsg <> 'Test message (34 bytes) no:') then
  215.     begin
  216.       inc(inErr);                  { lost some data, count errors and show }
  217.       gotoXY(50,8);
  218.       write('Lost data on ',inErr:4,' messages');
  219.     end;
  220.     tempMsg := copy(inMsg,1,34);
  221.     oldVideo := textAttr;
  222.     textBackground(Blue);
  223.     display(15,8,tempMsg);
  224.     textAttr := oldVideo;
  225.     updQueueGraf;
  226.   end;
  227. End;
  228.  
  229. { Flush both input and output queues by reading on the input side. The
  230.   bargraph is interesting during this test section. Since updating the
  231.   bargraph is relatively time consuming, and the update is done once
  232.   for every character read, characters are received faster than they
  233.   can be processed. The output buffer often has more data than can be
  234.   contained in the smaller input queue. As a result, the bargraph visually
  235.   shows the effect of transmission throttling by the protocol transfer }
  236. Procedure FlushQueues;
  237. Var
  238.   ch: char;
  239.  
  240. Begin
  241.   if keypressed then
  242.   begin
  243.     ch := readkey;
  244.     done := (ch = char(Esc));
  245.   end;
  246.   if not done then
  247.   begin
  248.     Status(Blue,'Flushing ...');
  249.     repeat
  250.       while (Comm1^.oCount > 0) or (Comm2^.iCount > 0) do
  251.       begin
  252.         ch := GetChar(Comm2,nil);
  253.         updQueueGraf;
  254.       end;
  255.       delay(10); {catch characters in transit - not in outq and not in inq }
  256.     until (Comm1^.oCount = 0) and (Comm2^.iCount = 0);
  257.   end;
  258.   gotoXY(15,8); write(' ':34); { erase displayed input message }
  259. End;
  260.  
  261. { Main program
  262.  
  263.     Displays a screen showing progress of the test. The test itself is
  264.     intended to do the following:
  265.  
  266.     1. Loop through various baud rates (starting with the high ones - so
  267.        test can be aborted when boredom sets in at lower rates).
  268.  
  269.     2. For each baud rate loop through the available protocols.
  270.  
  271.     3. For each configuration of baud rate and protocol run a test
  272.        consisting of some output and input messages. The number of
  273.        messages used depends on the line speed assigned for the current
  274.        test.
  275.  
  276.     4. Each test generates a sequence of output messages. These messages
  277.        are inserted in the COM1: output queue. Output is suspended when
  278.        a random upper limit is reached in the output queue (notice that
  279.        the output queue is larger than the COM2: receiving queue).
  280.  
  281.     5. When output is suspended, enter an idle loop to wait for an
  282.        appropriate amount of data to be received into the COM2: input
  283.        queue. The amount of data to be received during the idle is
  284.        either the amount required to empty the sending (COM1: output)
  285.        queue or the amount required to trigger COM1: output suspension
  286.        due to queue congestion in the COM2: input queue. Input queue
  287.        congestion is signalled differently, depending on the active
  288.        protocol.
  289.  
  290.     6. After the idle loop is finished, read some of the COM2: input
  291.        data. The amount read is determined by a random character count.
  292.        For each message read, check for message integrity. If any bad
  293.        messages are found, the screen will be updated to show a count
  294.        of bad messages.
  295.  
  296.     7. Before changing configuration (line speed or protocol), flush
  297.        all queues on both the input and the output side. Queues are
  298.        flushed by reading on the input side. Protocol handling is active
  299.        during the flush.
  300.  
  301.     8. During the entire testing process, display two bargraphs showing
  302.        the relative occupancy of the two queues. }
  303. Begin
  304.   Randomize;
  305.   InitScreen;
  306.   InitPorts;
  307.   done := false;
  308.   repeat
  309.     For testBaud := B38400 downto B1200 do {skip really slow rates }
  310.       For testProtocol := XoffProtocol to DsrProtocol do
  311.         if not done then
  312.         begin
  313.           testStart := timeStamp;
  314.           msgLimit := sqr(ord(testBaud)+1) * 8; { no of msgs in this test }
  315.           outCurMsgNo := 0;                     { init message counters }
  316.           inCurMsgNo := 0;
  317.           Config.Baud := testBaud;
  318.           Config.Protocol := testprotocol;
  319.           SetConfig(Comm1,Config);
  320.           SetConfig(Comm2,Config);
  321.           repeat
  322.             ChooseParams;                       { set buffer parametrs }
  323.             display(14,18,protocol_labels[ord(testProtocol)]);
  324.             gotoXY(51,18); write(baud_labels[ord(testBaud)],' ');
  325.             FillOutQ;                           { generate some output }
  326.             Idle;                               { idle until input received }
  327.             GetMessages;                        { retrieve the input }
  328.           until keypressed or (outCurMsgNo > msgLimit);
  329.           FlushQueues;                          { flush both queues }
  330.         end;
  331.   until done;                                   { until <esc> is typed }
  332.   FinishScreen;                                 { clean up screen }
  333. End.
  334.