home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ctcoll95.zip / PARALLEL / MCP.PAS < prev    next >
Pascal/Delphi Source File  |  1995-04-04  |  6KB  |  200 lines

  1. { MacPrint Centronics-Printer-Interface für Macintosh und andere     }
  2. { tcycle=1.0851 us bei 11,059 MHz Takt, 2764 EPROM                   }
  3. { Da nur rund 60 Bytes RAM zur Verfügung stehen, wurde konsequent    }
  4. { auf lokale Variable verzichtet. Der verwendete KSC-Pascal-Compiler }
  5. { Version 4.19 legt leider auch lokale Variable dauerhaft und nicht  }
  6. { auf dem Stack ab.                                                  }
  7. { P3.4 Baudrate, verbunden mit: }
  8. { --   1200                     }
  9. { P1.0 2400   (J3)              }
  10. { P1.1 4800   (J4)              }
  11. { P1.2 9600   (J5)              }
  12. { P1.3 19200  (J6)              }
  13. { P1.4 57600  (J7)              }
  14. { P3.7 Protokoll  (J1)          }
  15. { 0    XOn/XOff Software + CTS  }
  16. { 1    nur CTS Hardware         }
  17. { CTS wird immer bedient, egal, ob Soft- oder Hardware-Handshake.    }
  18. { Das Programm benutzt einen maxBuf großen Ringpuffer zur Vermeidung }
  19. { von allzu großem Handshake-Overhead, besonders bei XOn/XOff-Prot.  }
  20. { Auf Centronics-Seite wird nur BUSY, nicht jedoch /ACK ausgewertet. }
  21.  
  22. program macprint;
  23.  
  24.   const
  25.     VersStr = 'c''t-MacPrint (c) C.Meyer 4/95 V1.01 ';
  26.     msgStr1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ ';
  27.     msgStr2 = 'abcdefghijklmnopqrstuvwxyzäöü ';
  28.     msgStr3 = '0123456789!"$%&/()=[]*+#,.-  ';
  29.     high    = true;
  30.     low     = false;
  31.     HskCTS  = 2;      { Pins Port P3, Hsk/CTS Ausgang }
  32.     Strobe  = 3;      { Strobe zum Printer }
  33.     BdSel   = 4;      { Bits/s Sel  Jumper Common Pin }
  34.     Busy    = 5;      { high = Printer Busy }
  35.     AuxSel  = 6;
  36.     HardHsk = 7;      { high = Hardware-Handshake }
  37.  
  38.     maxBuf  = 31;     { Buffer-Größe }
  39.     fullBuf = 27;     { etwas Reserve zum Buffer-Ende }
  40.     XOn     = 17;     { Software-Handshake-Konstanten }
  41.     XOff    = 19;
  42.     Bd12    = 208;
  43.     Bd24    = 232;    { Timer-Konstanten für Baudrate }
  44.     Bd48    = 244;
  45.     Bd96    = 250;
  46.     Bd192   = 253;
  47.     Bd576   = 255;
  48.  
  49.   type
  50.     bufType = packed array[0..maxbuf] of byte;
  51.  
  52.   var
  53.     Iptr,Lptr: byte;
  54.     dataBuf: BufType; { Ringpuffer für eingehende Daten }
  55.     x: byte;
  56.     countInt:Integer;
  57.     XOnSent: Boolean;
  58.  
  59. {************************* Interrupt-Routinen ****************************}
  60.  
  61.   procedure interrupt serial;
  62. { Char in SBUF angekommen oder komplett gesendet }
  63.   begin
  64.     if RI then
  65.       begin
  66.         dataBuf[Iptr]:=SBUF;
  67.         RI:=false;
  68.         inc(Iptr);
  69.         if Iptr > maxBuf then
  70.           Iptr:=0;
  71. { bevor Buffer überfahren wird: feststellen, ob Grenzwert erreicht }
  72.         if abs(IPtr-LPtr) > fullBuf then
  73.           begin
  74.             P3.HskCTS:=high;   { Einen Moment...    CTS-Handshake sperren }
  75.             if XOnSent and (not P3.HardHsk) then    { XOn/XOff-Enable-Pin }
  76.               begin            { XOff senden, sofern noch nicht geschehen }
  77.                 TI := false;
  78.                 SBUF:=XOff;
  79.                 XOnSent:=false;
  80.               end;
  81.           end;
  82.       end;
  83.     if TI then
  84. { da XOn/XOff relativ selten gesendet wird, muß nicht auf erfolgte }
  85. { Übertragung gewartet werden. Gesetztes TI landet irgendwann hier }
  86.       TI:=false;
  87.   end;
  88.  
  89. {************************* Low-Level-Routinen ****************************}
  90.  
  91.   procedure wait(zehntelsec:integer);
  92. { Zehntelsekunden abgestimmt auf 11,059 MHz Takt }
  93.   begin
  94.     for countInt:= 0 to zehntelsec*43 do
  95.       for x:=0 to 253 do
  96.   end;
  97.  
  98.   procedure rwait;
  99. { Für Timing: Luxus-NOP, incl. Aufruf 10 us bei 11,059 MHz }
  100.   begin
  101.     x:=x;
  102.     x:=x;
  103.   end;
  104.  
  105.  
  106. {************************* allgemeine Routinen ***************************}
  107.  
  108.   procedure ParOut(theByte:byte);
  109. { Byte in Centronics-Manier ausgeben, 10us /Strobe }
  110.   begin
  111.     P1:=theByte;
  112.     rwait;
  113.     P3.Strobe:=low;
  114.     rwait;
  115.     P3.Strobe:=high;
  116.     rwait;
  117.     repeat
  118.     until not P3.Busy;  { Busy abwarten }
  119.     rwait;              { Ack  abwarten: 30us maximal }
  120.     rwait;
  121.     rwait;
  122.     P1:=$FF;
  123.   end;
  124.  
  125.   procedure message;
  126.   begin
  127.     repeat
  128.       for x:= 1 to 128 do
  129.         ParOut(byte(VersStr[x]));
  130.     until P3.AuxSel;
  131.   end;
  132.  
  133. {*************************** Hauptschleife *******************************}
  134.  
  135. begin
  136.   reset(serial);
  137.   IE:=0;
  138.   PS:=true;              { Serial höchste Priorität  }
  139.   ES:=true;              { Serial input Int enable   }
  140.   EA:=true;              { Interrupt enable          }
  141.   P3:=$FF;
  142.   P3.HskCTS:=low;        { HskIn Mac freigeben       }
  143.   RI:=false;             { Interrupt-Flag löschen    }
  144.   for x:=0 to maxBuf do  { Buffer initialisieren     }
  145.     dataBuf[x]:=0;
  146.   XOnSent:=false;        { XOn noch nicht gesendet   }
  147.   x:=$FE;
  148.   Iptr:=0;
  149.   for Lptr := 1 to 5 do
  150.     begin
  151. { alle Bit/s Jumper abfragen }
  152.       P1:=x;
  153.       if not P3.BdSel then Iptr := Lptr;
  154.       x:= 1 or (x shl 1);
  155.     end;
  156.   case Iptr of
  157.     0: TH1:=Bd12;        { 1200  bit/s, 1mal blinken (kein Jumper) }
  158.     1: TH1:=Bd24;        { 2400  bit/s, 2mal blinken (J3) }
  159.     2: TH1:=Bd48;        { 4800  bit/s, 3mal blinken (J4) }
  160.     3: TH1:=Bd96;        { 9600  bit/s, 4mal blinken (J5) }
  161.     4: TH1:=Bd192;       { 19200 bit/s, 5mal blinken (J6) }
  162.     5: TH1:=Bd576;       { 57600 bit/s, 6mal blinken (J7) }
  163.   end;
  164.   for Lptr := 0 to Iptr do
  165.     begin                { Blinken zur Funktionskontrolle }
  166.       P1:=$55;
  167.       wait(2);
  168.       P1:=$AA;
  169.       wait(2);
  170.     end;
  171.   P1:=$FF;
  172.   Iptr:=0;               { Interrupt-Pointer und }
  173.   Lptr:=0;               { Loop-Pointer auf Daten-Array }
  174.  
  175.   repeat
  176.     if not P3.AuxSel then
  177.       message;
  178.     if IPtr<>LPtr then   { Buffer abgearbeitet? }
  179.       begin
  180.         ParOut(dataBuf[Lptr]);
  181.         inc(Lptr);
  182.         if Lptr > MaxBuf then
  183.           LPtr:=0;       { immer im Kreis }
  184.       end
  185.     else
  186. { CTS-Freigabe-Impuls und XOn für Handshake }
  187.       begin
  188.         P3.HskCTS:=low;  { weiter gehts: CTS freigeben }
  189.         if (not XOnSent) and (not P3.HardHsk) then
  190.           begin          { XOn senden, sofern noch nicht geschehen }
  191.             TI:=false;
  192.             SBUF:=XOn;
  193.             XOnSent := true;
  194.           end;
  195.         P1:=$FE;         { LED dimmen (PWM) }
  196.         P1:=$FF;
  197.       end;
  198.   until false;
  199. end.
  200.