home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj9105.zip / STRUC_PR.ASC < prev    next >
Text File  |  1991-03-15  |  6KB  |  177 lines

  1. _STRUCTURED PROGRAMMING COLUMN_
  2. by Jeff Duntemann
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7.  
  8. CONST
  9.   COMPORT  = 2;               {  1 = COM1:  2 = COM2: }
  10.   COMBASE  = $2F8;
  11.   PORTBASE = COMBASE OR (COMPORT SHL 8); { $3F8 for COM1: $2F8 for COM2: }
  12.  
  13.   { 8250 control registers, masks, etc. }
  14.   RBR      = PORTBASE;        { 8250 Receive Buffer Register       }
  15.   THR      = PORTBASE;        { 8250 Transmit Holding Register     }
  16.   IER      = PORTBASE + 1;    { 8250 Interrupt Enable Register     }
  17.   LCR      = PORTBASE + 3;    { 8250 Line Control Register         }
  18.   MCR      = PORTBASE + 4;    { 8250 Modem Control Register        }
  19.   LSR      = PORTBASE + 5;    { 8250 Line Status Register          }
  20.  
  21.   DLL      = PORTBASE;        { 8250 Divisor Latch LSB when DLAB=1 }
  22.   DLM      = PORTBASE + 1;    { 8250 Divisor Latch MSB when DLAB=1 }
  23.  
  24.   DLAB     = $80;     { Value for Divisor Latch Access Bit  }
  25.   THRE     = $20;     { Value for Transmit Holding Register Empty bit }
  26.   BAUD300  = 384;     { Value for 300 baud operation        }
  27.   BAUD1200 = 96;      { Value for 1200 baud operation       }
  28.   DTR      = $01;     { Value for Data Terminal Ready       }
  29.   RTS      = $02;     { Value for Ready To Send             }
  30.   NOPARITY = 0;       { Comm format value for no parity     }
  31.   BITS8    = $03;     { Comm format value for 8 bits        }
  32.  
  33.  
  34.  
  35.  
  36. [LISTING TWO]
  37.  
  38. {--------------------------------------------------------------}
  39. {                         POLLTERM                             }
  40. {                             by Jeff Duntemann                }
  41. {                             Turbo Pascal V6.0                }
  42. {                             Last update 2/3/91               }
  43. { This is a *truly* dumb terminal program that operates by     }
  44. { polling the serial port's registers and does NOT use         }
  45. { interrupts.  It's a good illustration of why interrupts are  }
  46. { necessary...                                                 }
  47. { PollTerm can be set to use either COM1: or COM2: by setting  }
  48. { the COMPORT constant to 1 (for COM1) or 2 (for COM2:) as     }
  49. { as appropriate and recompiling.                              }
  50. {--------------------------------------------------------------}
  51.  
  52. PROGRAM PollTerm;
  53.  
  54. USES DOS,CRT;
  55.  
  56. {$I REGISTERS.DEF }
  57.  
  58. VAR
  59.   Quit       : Boolean;      { Flag for exiting the program }
  60.   HiBaud     : Boolean;      { True if 1200 baud is being used }
  61.   KeyChar    : Char;         { Character from keyboard }
  62.   CommChar   : Char;         { Character from the comm port }
  63.   Divisor    : Word;         { Divisor value for setting baud rate }
  64.   Clearit    : Byte;         { Dummy variable }
  65.   NoShow     : SET OF Char;  { Don't show characters set }
  66.  
  67. PROCEDURE SetRate(Divisor : Word);
  68.  
  69. BEGIN
  70.   { Set the DLAB flag to 1: }
  71.   Port[LCR] := Port[LCR] OR DLAB;
  72.   { Load the divisor latches: }
  73.   Port[DLL] := Lo(Divisor);
  74.   Port[DLM] := Hi(Divisor);
  75.   { Clear the DLAB flag to 0:}
  76.   Port[LCR] := Port[LCR] AND (NOT DLAB);
  77. END;
  78.  
  79. FUNCTION InStat : Boolean;
  80.  
  81. BEGIN
  82.   { Bit 0 of LSR goes high when a char is waiting: }
  83.   InStat := Boolean(Port[LSR] AND $01);
  84. END;
  85.  
  86. FUNCTION OutStat : Boolean;
  87.  
  88. BEGIN
  89.   { Bit 5 of LSR goes high when the THR is ready for another char: }
  90.   OutStat := ((LSR AND THRE) = THRE);
  91. END;
  92.  
  93. FUNCTION InChar : Char;
  94.  
  95. BEGIN
  96.   InChar := Char(Port[RBR]);
  97. END;
  98.  
  99. PROCEDURE OutChar(Ch : Char);   { Send a character to the comm port }
  100.  
  101. BEGIN
  102.   Port[THR] := Byte(Ch)     { Put character ito Transmit Holding Register }
  103. END;
  104.  
  105. PROCEDURE UhUh;
  106.  
  107. VAR
  108.   I : Integer;
  109.  
  110. BEGIN
  111.   FOR I := 1 TO 2 DO
  112.     BEGIN
  113.       Sound(50);
  114.       Delay(50);
  115.       NoSound;
  116.       Delay(50);
  117.     END;
  118. END;
  119.  
  120.  
  121. {>>>>>POLLTERM MAIN PROGRAM<<<<<}
  122.  
  123. BEGIN
  124.   HiBaud := True;               { PollTerm defaults to 1200 baud; if "300"}
  125.   Divisor := BAUD1200;          { is entered after "POLLTERM" on the      }
  126.   IF ParamCount > 0 THEN        { command line, then 300 baud is used     }
  127.     IF ParamStr(1) = '300' THEN
  128.       BEGIN
  129.         HiBaud := False;
  130.         Divisor := BAUD300
  131.       END;
  132.  
  133.   SetRate(Divisor);                 { Set the baud rate           }
  134.  
  135.   Port[IER] := 0;                   { Disable 8259 interrupts     }
  136.   Port[LCR] := BITS8 OR NOPARITY;   { Set word length and parity  }
  137.   Port[MCR] := DTR OR RTS;          { Enable DTR, & RTS }
  138.   Clearit := Port[RBR];             { Clear any garbage from RBR  }
  139.   Clearit := Port[LSR];             { Clear any garbage from LSR  }
  140.  
  141.   DirectVideo := True;
  142.   NoShow := [#0,#127];              { Don't display NUL or RUBOUT }
  143.  
  144.   ClrScr;
  145.   Writeln('>>>POLLTERM by Jeff Duntemann');
  146.  
  147.   Quit := False;        { Exit POLLTERM when Quit goes to True }
  148.   REPEAT
  149.  
  150.     IF InStat THEN      { If a character comes in from the modem }
  151.       BEGIN
  152.         CommChar := InChar;                        { Go get character  }
  153.         CommChar := Char(Byte(CommChar) AND $7F);  { Mask off high bit }
  154.         IF NOT (CommChar IN NoShow) THEN           { If we can show it,}
  155.           Write(CommChar)                          {  then show it! }
  156.       END;
  157.  
  158.     IF KeyPressed THEN  { If a character is typed at the keyboard }
  159.       BEGIN
  160.         KeyChar := ReadKey;       { First, read the keystroke }
  161.         IF KeyChar = Chr(0) THEN  { We have an extended scan code here }
  162.           UhUh                    {   but we're not using it! }
  163.         ELSE
  164.         CASE Ord(KeyChar) OF
  165.          24 : Quit := True;   { Ctrl-X: Exit PollTerm }
  166.          26 : ClrScr;         { Ctrl-Z: Clear the screen }
  167.          ELSE BEGIN
  168.                 WHILE NOT OutStat DO BEGIN END;  { I.e., nothing }
  169.                 OutChar(KeyChar)
  170.               END;
  171.         END;  { CASE }
  172.       END
  173.  
  174.   UNTIL Quit
  175. END.
  176.  
  177.