home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9303 / block / lz.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1993-06-14  |  26.6 KB  |  588 lines

  1. (* ------------------------------------------------------ *)
  2. (*                        LZ.PAS                          *)
  3. (*           Residentes Linienzeichenprogramm             *)
  4. (*         (c) 1993 Martin Wölker & DMV-Verlag            *)
  5. (* ------------------------------------------------------ *)
  6. PROGRAM Linien_zeichnen;
  7. {$F-,R-,S-,I-,V-,B-,N-,D-,G+}      (* Keine Tests; 286 an *)
  8. {$M 1024,0,0}                      (* minimaler Speicher  *)
  9.  
  10. USES Crt, Dos;
  11.  
  12. CONST
  13.   Kennung = $0202;            { Versionsnummer als Kennung }
  14.   Datum   = '04-28-1993';       
  15.   Zeile : STRING [20] = 'DOS toolbox 3/1993';
  16.                   { wird auch als Zwischenspeicher genutzt }
  17.  
  18.   SoftKey       : WORD       = $7100;              
  19.   Tasten_String : STRING [9] = '<ALT-F10>'; 
  20.  
  21. {       Position der "Aktiv"-Anzeige: diese Position kann  }
  22.   xOut : BYTE = 72;        { Spalte   beim Start der TSR   }
  23.   yOut : BYTE =  1;        { Zeile    frei bestimmt werden }
  24.  
  25. { Mit größeren Pufferlängen kann man natürlich auch andere }
  26.                        {            Funktionen realisieren }
  27.   Maxlen = 4;          { maximale Länge des Ausgabepuffers }
  28.  
  29. {      Modusschalter für den Betriebszustand des Programms }
  30.   LZ_on_off : BYTE = 0;          {  0 --> Wartestellung    }
  31.                                  {             Sleep-Modus }
  32.                                  {  1 --> Zeichnen         }
  33.                                  {               KBD-Modus }
  34.                                  {  2 --> Ausgabe erzeugen }
  35.                                  {               OUT-Modus }
  36.  
  37. {  Tastaturcodes (ermittelt mit Scancode) mit 2 Funktionen }
  38.   right =$4D00; left =$4b00;    { 1.: Auslesen der         }
  39.   up    =$4800; Down =$5000;    {     Tastatur             }
  40.   sright=$4D36; Sleft=$4B34;    { 2.: Versorgung des       }
  41.   sup   =$4838; Sdown=$5032;    {     aktuellen  Programms }
  42.   ins   =$5200; del  =$5300;    {     mit Steuerzeichen    }
  43.  
  44. { Schalter für den internen Betriebszustand des Programms  }
  45.   insert_on:  {  TRUE: Das Programm erzeugt zu jedem Zei-  }
  46.     BOOLEAN=  {        chen ein Del um das automatische    }
  47.     TRUE;     {        Einfügen des Editors auszugleichen. }
  48.               { FALSE: Stattdessen wird eine Nulleingabe   }
  49.               {        erzeugt                             }
  50.  
  51. TYPE
  52.   typen = (s,d,p,n); { vier definierte Linientypen         }
  53.         {  │ │ │ └──── unterbrochen                        }
  54.         {  │ │ └────── gepunktet                           }
  55.         {  │ └──────── doppelliniert                       }
  56.         {  └────────── einfachliniert                      }
  57.         {            │ <── Defaulteinstellung Einfachlinie }
  58. CONST
  59.   LZ_Typ      :  typen = s;  { aktueller Linientyp         }
  60.   typ_char    :  ARRAY[typen] OF CHAR  { Umschaltzeichen   }
  61.               = ('s'    ,'d'    ,'p'    ,'u'    );
  62.   LZ_typ_char :  ARRAY[typen] OF CHAR  { Anzeigezeichen    }
  63.               = ('─'    ,'═'    ,'∙'    ,'|'    );
  64.   LZ_typ_color:  ARRAY[typen] OF BYTE  { Anzeigefarbe      }
  65.               = (red    ,green  ,cyan   ,magenta);
  66.   dummy_signs :  ARRAY[1..2,typen] OF CHAR = { Dummies für }
  67.               (('─','═','∙','-'),            { Tastatur-   }
  68.                ('│','║',':','|'));           { simulation  }
  69.  
  70. { Tabellen zur Interpretation des Bildschirms }
  71. TYPE
  72.   allowed_signs = STRING[13];   { Alle Zeichen, die in der }
  73. { jeweiligen Richtung als benachbarte Zeichen erlaubt sind.}
  74. CONST
  75.   singleleft : allowed_signs = '┌┬├┼└┴─╓╥╟╫╙╨';
  76.   singleright: allowed_signs = '┬┐┼┤┴┘─╥╖╫╢╨╜';
  77.   singleup   : allowed_signs = '┌┬┐├┼┤│╒╤╕╞╪╡';
  78.   singledown : allowed_signs = '├┼┤└┴┘│╞╪╡╘╧╛';
  79.   doubleleft : allowed_signs = '╔╦╠╬╚╩═╒╤╞╪╘╧';
  80.   doubleright: allowed_signs = '╦╗╬╣╩╝═╤╕╪╡╧╛';
  81.   doubleup   : allowed_signs = '╔╦╗╠╬╣║╓╥╖╟╫╢';
  82.   doubledown : allowed_signs = '╠╬╣╚╩╝║╟╫╢╙╨╜';
  83.   pointhor   : CHAR          = '∙';
  84.   pointver   : CHAR          = ':';
  85.   dashedhor  : CHAR          = '-';
  86.   dashedver  : CHAR          = '|';
  87.  
  88. TYPE
  89.   Tablechars  = ARRAY[1..3,1..3] OF CHAR;
  90.   tablecodes  = ARRAY[1..3,1..3] OF WORD;
  91. CONST
  92.   allframe : ARRAY[1..9] OF tablechars =
  93.            ( { Zuerst für gerade Linien }
  94.              ('───','∙∙∙','═══'),   { jeweils 3 Zeichen    }
  95.              ('│││',':::','║║║'),   { rechts/links/re&li   }
  96.              ('---','|||','???'),   { oben/unten/ob&unten  }
  97.              { Alle Kombinationen aus Vertikal/Horizontal  }
  98.              ('┌┬┐',                {                      }
  99.               '├┼┤',                { V:einfach            }
  100.               '└┴┘'),               { H:einfach            }
  101.              ('╔╦╗',                {                      }
  102.               '╠╬╣',                { V:Doppelt            }
  103.               '╚╩╝'),               { H:Doppelt            }
  104.              ('╓╥╖',                {                      }
  105.               '╟╫╢',                { V:Doppelt            }
  106.               '╙╨╜'),               { H:Einfach            }
  107.              ('╒╤╕',                {                      }
  108.               '╞╪╡',                { V:Einfach            }
  109.               '╘╧╛'),               { H:Doppelt            }
  110.              ('∙:∙',                {                      }
  111.               ':::',                { V:Gepunktet          }
  112.               '∙:∙'),               { H:Gepunktet          }
  113.              ('┌┬┐',                {                      }
  114.               '|||',                { V:gestrichelt        }
  115.               '└┴┘'));              { H:gestrichelt        }
  116.  
  117. {              Lo(code)                      Hi(code)      }
  118. {┌─────────────────┴─────────────────┐   ┌───────┴───────┐ }
  119. {│                                   │   │               │ }
  120. {   16        32        32        16        16        32   }
  121. { 1 ┼ 4     2 ╬ 8     1 ╫ 4     2 ╪ 8     1 : 4     2 | 8  }
  122. {   64       128       128        64        64       128   }
  123.  
  124.   codes:ARRAY[1..9] OF tablecodes= (       { Umsetztabelle }
  125.  ((    4,    5,    1),(  256, 1280, 1024), {               }
  126.   (    8,   10,    2)),                    { Nach der Be-  }
  127.  ((   64,   80,   16),( 4096,20480,16384), { stimmung des  }
  128.   (  128,  160,   32)),                    { Codes, wird   }
  129.  ((  512, 2560, 2048),( 8192,40960,32768), { dieser hier   }
  130.   (    0,    0,    0)),                    { gesucht.      }
  131.  ((   68,   69,   65),(   84,   85,   81), { Mit dem Index }
  132.   (   20,   21,   17)),                    { i,j,k wird    }
  133.  ((  136,  138,  130),(  168,  170,  162), { das richtige  }
  134.   (   40,   42,   34)),                    { Zeichen aus   }
  135.  ((  132,  133,  129),(  164,  165,  161), { der Tabelle   }
  136.   (   36,   37,   33)),                    { allframe s.o. }
  137.  ((   72,   74,   66),(   88,   90,   82), { entnommen.    }
  138.   (   24,   26,   18)),                    { Danach wird   }
  139.  ((17408,17664,16640),(21504,21760,20736), { Schreibpuffer }
  140.   ( 5120, 5376, 4352)),                    { gefüllt.      }
  141.  ((34816,35328,33280),(43008,43520,41472), {               }
  142.   (10240,10752, 8704))             );
  143.  
  144. TYPE
  145.   TScreen = ARRAY[1..25,1..80] OF WORD;
  146.  
  147. VAR
  148.     SCR_Segment : ^TScreen;
  149.  
  150.     int16save:POINTER; { INT $16 beim Installieren der TSR }
  151.  
  152.     LZBuffer:ARRAY[1..maxlen] OF WORD; { Ausgabepuffer     }
  153.     bufpos,                            { aktuelle Position }
  154.     buflength:BYTE;                    { wirkliche Länge   }
  155.  
  156. {           Variablen mit dem Code aus der Zeichenumgebung }
  157.     code:WORD;                         {  Die Codevariable }
  158.     acode:ARRAY[1..2] OF BYTE { Damit kann man dem Lo- und }
  159.       ABSOLUTE code;      { Hi-Byte einfach Werte zuweisen }
  160.  
  161.     r,l,u,o:CHAR;                      {   die Textzeichen }
  162.             { in der Umgebung der aktuellen Cursorposition }
  163.     i,j,k:byte;                        { indices für die   }
  164.             { Suche des richtigen Zeichens bei Bewegungen  }
  165.     x,y:byte;
  166.     Regs:REGISTERS;
  167.  
  168. (**********************************************************)
  169. (* Hilfsroutinen    hier: Steuerung                       *)
  170. (**********************************************************)
  171.  
  172. FUNCTION KeyFromOldInt16 :WORD;
  173.   INLINE ($31/$C0/$9C/$FF/$1E/Int16Save);
  174.  
  175. PROCEDURE ExitOldInt16;
  176.   INLINE ($A1/Int16Save+2/$87/$46/$10/$8B/$1E/Int16Save/
  177.           $87/$5E/$0E/$5D/$07/$1F/$5F/$5E/$5A/$59/$CB);
  178.  
  179. (**********************************************************)
  180. (* Hilfsroutinen    hier: Schreibroutinen                 *)
  181. (**********************************************************)
  182.  
  183. PROCEDURE Write_LZ;
  184. {***  Schreibt eine Status-Anzeige an die Position x,y  ***}
  185. BEGIN
  186.  TextColor(black);                           { Textfarbe   }
  187.  TextBackground(LZ_typ_color[lz_typ]);       { Hintergrund }
  188.  x:=WhereX;                                  { Cursorpos   }
  189.  y:=WhereY;                                  { retten      }
  190.  GotoXY(xout,yout);                          { Ausgabepos  }
  191.  Write('LZ:',LZ_typ_char[lz_typ]);           { "LZ" zeigen }
  192.  IF insert_on THEN                           { TSR im ───┐ }
  193.    Write(' ins')                             { insertmod │ }
  194.  ELSE                                        { oder      │ }
  195.    Write('    ');                            { überschr.─┘ }
  196.  GotoXY(x,y);                                { alte Pos    }
  197.  NormVideo;                                  { alte Farben }
  198. END;
  199.  
  200. PROCEDURE Write_buffer_to_kbd;
  201. {*** Schreibt das nächste Zeichen in den Tastaturpuffer ***}
  202. BEGIN
  203.   IF bufpos=buflength THEN BEGIN        { Puffer leer dann }
  204.     LZ_on_off:=1;    { zurückschalten in Tastatursteuerung }
  205.     EXIT;
  206.   END;
  207.   INC(bufpos);
  208.   regs.Ah:=5; regs.cx:=LZBuffer[bufpos]; Intr($16,Regs);
  209. END;
  210.  
  211.  
  212. PROCEDURE Write_false_key;
  213. {*** Fehlermeldung, bei unzulässigen Tastatureingaben   ***}
  214. BEGIN  Sound(200); Delay(20); NoSound; END;
  215.  
  216.  
  217. (**********************************************************)
  218. (* Hauptteil  Suchen, Puffer füllen, Tastaturinterrupt    *)
  219. (**********************************************************)
  220.  
  221. PROCEDURE Suche_zeichen(Cursor_move:WORD);
  222. {╔════════════════════════════════════════════════════════╗}
  223. {║ Suchroutine: Setzt die Zeichen in der Umgebung des     ║}
  224. {║              Cursors und Cursor_move in ein Code-Wort  ║}
  225. {║              um, das wiederum den Index für das kor-   ║}
  226. {║              rekte Linienelement bestimmt.             ║}
  227. {╚════════════════════════════════════════════════════════╝}
  228. BEGIN
  229. {                                Alte Umgebung löschen ──┐ }
  230.     l:=' ';                                  {           │ }
  231.     r:=' ';                                  {           │ }
  232.     o:=' ';                                  {           │ }
  233.     u:=' ';                                  { ──────────┘ }
  234.  
  235. { Lesen der Zeichen in der Umgebung der Cursorposition ──┐ }
  236.   x:=WhereX; y:=WhereY;                      { Cursorpos │ }
  237.   IF x>1  THEN                               {           │ }
  238.     l:=CHAR(Lo(scr_segment^[y,Pred(x)]));    { links     │ }
  239.   IF x<80 THEN                               {           │ }
  240.     r:=CHAR(Lo(scr_segment^[y,Succ(x)]));    { rechts    │ }
  241.   IF y>1  THEN                               {           │ }
  242.     o:=CHAR(Lo(scr_segment^[Pred(y),x]));    { oben      │ }
  243.   IF y<25 THEN                               {           │ }
  244.     u:=CHAR(Lo(scr_segment^[Succ(y),x]));    { unten     │ }
  245.   CASE cursor_move                           { Cursor-   │ }
  246.     OF                                       { moves  ──┐│ }
  247.     right : r:=dummy_signs[1,LZ_typ];        {  RECHTS  ││ }
  248.     left  : l:=dummy_signs[1,LZ_typ];        {  LINKS   ││ }
  249.     up    : o:=dummy_signs[2,LZ_typ];        {  OBEN    ││ }
  250.     down  : u:=dummy_signs[2,LZ_typ];        {  UNTEN   ││ }
  251.   END; {case}                                { simulieren│ }
  252.                                              { ──────────┘ }
  253.  
  254. {                              analysieren der Zeichen ──┐ }
  255. {                     pointleft  doubledown              │ }
  256. {                  dashedleft │  │ singledown            │ }
  257. {                pointright │ │  │ │ doubleup            │ }
  258. {             dashedright │ │ │  │ │ │ singleup          │ }
  259. {               pointup │ │ │ │  │ │ │ │ doubleright     │ }
  260. {            dashedup │ │ │ │ │  │ │ │ │ │ singleright   │ }
  261. {         pointdown │ │ │ │ │ │  │ │ │ │ │ │ doubleleft  │ }
  262. {      dasheddown │ │ │ │ │ │ │  │ │ │ │ │ │ │ singleleft│ }
  263. {               │ │ │ │ │ │ │ │  │ │ │ │ │ │ │ │         │ }
  264. { Bits in Code 10 F D E C B A 9  8 7 6 5 4 3 2 1         │ }
  265. {                                                        │ }
  266.   code:=0;                                   { löschen   │ }
  267.   IF (lz_typ=s) OR (LZ_typ=d) THEN BEGIN     { s oder d ┐│ }
  268.     IF pos(l,singleleft)>0  THEN             { LO(code) ││ }
  269.       INC(acode[1],1);                       { setzen │ ││ }
  270.     IF pos(l,doubleleft)>0  THEN             {        │ ││ }
  271.       INC(acode[1],2);                       {        │ ││ }
  272.     IF pos(r,singleright)>0 THEN             {        │ ││ }
  273.       INC(acode[1],4);                       {        │ ││ }
  274.     IF pos(r,doubleright)>0 THEN             {        │ ││ }
  275.       INC(acode[1],8);                       {        │ ││ }
  276.     IF pos(o,singleup)>0    THEN             {        │ ││ }
  277.       INC(acode[1],16);                      {        │ ││ }
  278.     IF pos(o,doubleup)>0    THEN             {        │ ││ }
  279.       INC(acode[1],32);                      {        │ ││ }
  280.     IF pos(u,singledown)>0  THEN             {        │ ││ }
  281.       INC(acode[1],64);                      {        │ ││ }
  282.     IF pos(u,doubledown)>0  THEN             {        │ ││ }
  283.       INC(acode[1],128);                     { ───────┘ ││ }
  284.   END                                        { ─────────┘│ }
  285.   ELSE                                       { sonst     │ }
  286.   IF LZ_typ=p THEN BEGIN                     { points ──┐│ }
  287.     IF l = pointhor       THEN               { HI(code) ││ }
  288.       INC(acode[2],1);                       { setzen   ││ }
  289.     IF r = pointhor       THEN               {          ││ }
  290.       INC(acode[2],4);                       {          ││ }
  291.     IF o = pointver    THEN                  {          ││ }
  292.       INC(acode[2],16);                      {          ││ }
  293.     IF u = pointver   THEN                   {          ││ }
  294.       INC(acode[2],64);                      {          ││ }
  295.   END                                        { ─────────┘│ }
  296.   ELSE                                       { sonst     │ }
  297.   IF LZ_typ=n THEN BEGIN                     { dashed ──┐│ }
  298.     IF pos(l,dashedhor+singleleft)>0  THEN   { HI(code) ││ }
  299.       INC(acode[2],2);                       { setzen │ ││ }
  300.     IF pos(r,dashedhor+singleright)>0 THEN   {        │ ││ }
  301.       INC(acode[2],8);                       {        │ ││ }
  302.     IF pos(o,dashedver+singleup)>0    THEN   {        │ ││ }
  303.       INC(acode[2],32);                      {        │ ││ }
  304.     IF pos(u,dashedver +singledown)>0 THEN   {        │ ││ }
  305.        INC(acode[2],128);                    { ───────┘ ││ }
  306.   END;                                       { ─────────┴┘ }
  307. {                Hier kann man den Inhalt von Code ansehen }
  308. { GotoXY(1,1);                               {           │ }
  309. { FOR i:=15 DOWNTO 0 DO                      {           │ }
  310. {   write(code AND (1 SHL i) SHR i);         {           │ }
  311. {                                              ──────────┘ }
  312.  
  313. {     gegenüberliegende  einfach/doppelt Wiedersprüche ──┐ }
  314.   IF                                         { verboten ┐│ }
  315.     (code AND $0009=$0009) OR                { sl«»dr   ││ }
  316.     (code AND $0006=$0006)                   { dl«»sr   ││ }
  317.   THEN BEGIN                                 { ─────────┘│ }
  318.     code:= code AND $F0F0;                   { löschen   │ }
  319.     IF LZ_typ=s THEN                         { setzen ──┐│ }
  320.       INC(code,5)                            { einfach  ││ }
  321.     ELSE IF LZ_typ=d THEN                    {          ││ }
  322.      INC(code,10);                           { doppelt  ││ }
  323.   END;                                       { ─────────┘│ }
  324.   IF                                         { verboten ┐│ }
  325.     (code AND $0090=$0090) OR                { su«»dd   ││ }
  326.     (code AND $0060=$0060)                   { du«»sd   ││ }
  327.   THEN BEGIN                                 { ─────────┘│ }
  328.     code:= code AND $0F0F;                   { löschen   │ }
  329.     IF LZ_typ=s THEN                         { setzen───┐│ }
  330.       INC(code,80)                           { einfach  ││ }
  331.     ELSE IF LZ_typ=d THEN                    {          ││ }
  332.      INC(code,160);                          { doppelt  ││ }
  333.   END;                                       { ─────────┴┘ }
  334.  
  335. {                               ermitteln des Zeichens ──┐ }
  336.   For i:= 1 to 9 do                          { INC(i,j,k)│ }
  337.     For j:=1 to 3 do                         { und ver-  │ }
  338.       For k:=1 to 3 do                       { lassen,   │ }
  339.         if code=codes[i,j,k] then            { wenn      │ }
  340.           EXIT;                              { gefunden  │ }
  341. END;
  342.  
  343. PROCEDURE Fill_buffer(Cursor_move:WORD);
  344. {╔════════════════════════════════════════════════════════╗}
  345. {║ Puffer mit den richtigen Zeichen füllen.               ║}
  346. {╚════════════════════════════════════════════════════════╝}
  347. BEGIN
  348.   buflength:=1;
  349.   Bufpos:=1;
  350.       {  Steuertasten mit Shift nur einfach weitergeben ─┐ }
  351.   CASE cursor_move OF                        {           │ }
  352.     sleft  : LZBuffer[1]:=left;              {           │ }
  353.     sright : LZBuffer[1]:=right;             {           │ }
  354.     sup    : LZBuffer[1]:=up;                {           │ }
  355.     sdown  : LZBuffer[1]:=down;              {           │ }
  356.   ELSE BEGIN                 { Linienelement berechnen ──┐ }
  357.     Suche_Zeichen(cursor_move);              {<<SUCHEN>> │ }
  358.     buflength:=4;                            {           │ }
  359.     IF insert_on THEN                        { insertmode│ }
  360.       LZBuffer[1]:=del                       { weg     │ │ }
  361.     ELSE                                     { sonst ──┤ │ }
  362.       LZBuffer[1]:=$00;                      { nix     │ │ }
  363.                                              {     ────┘ │ }
  364.       LZBuffer[2]:=$00+BYTE(allframe[i,j,k]);{           │ }
  365.       LZBuffer[3]:=left;                     {           │ }
  366.       LZBuffer[4]:=cursor_move;              {           │ }
  367.     END;                                     {         ──┘ }
  368.   END {case};                                {             }
  369.   LZ_on_off:=2;           { Umschalten in den Ausgabemodus }
  370. END;
  371.  
  372. procedure toggle_lz;
  373. {╔════════════════════════════════════════════════════════╗}
  374. {║ Schaltet die TSR an bzw aus.                           ║}
  375. {╚════════════════════════════════════════════════════════╝}
  376. BEGIN
  377.   IF LZ_on_off=1 THEN BEGIN               { TSR ist an ──┐ }
  378.     Move(Zeile,scr_segment^[yout,xout],16);{Restaurieren │ }
  379.     LZ_on_off:=0;                         { ausschalten  │ }
  380.   END                                     {         ─────┘ }
  381.   ELSE BEGIN                              { TSR ist aus ─┐ }
  382.     Move(scr_segment^[yout,xout],zeile,16);{Sichen       │ }
  383.     LZ_on_off:=1;                         { anschalten   │ }
  384.     write_LZ;                             { Marke        │ }
  385.   END;                                    {         ─────┘ }
  386. END;
  387.  
  388. procedure lz_function(var ax:WORD);
  389. {╔════════════════════════════════════════════════════════╗}
  390. {║ Interpretation der Tastatureingaben                    ║}
  391. {║          1. Cursorbewegungeninterpretieren             ║}
  392. {║          2. Linienzeichener steuern                    ║}
  393. {╚════════════════════════════════════════════════════════╝}
  394. BEGIN
  395.   CASE AX OF                          { Welche Taste ? ───┐}
  396.     right,                { rechts      ╔══════════════╗  │}
  397.     left,                 { links       ║  Bewegungen  ║  │}
  398.     up,                   { rauf        ║interpretieren║  │}
  399.     down,                 { runter      ╚══════════════╝  │}
  400.     sright,               { shiftrechts ╔══════════════╗  │}
  401.     sleft,                { shiftlinks  ║  Bewegungen  ║  │}
  402.     sup,                  { shiftrauf   ║ weiterreichen║  │}
  403.     sdown  : BEGIN        { shiftrunter ╚══════════════╝  │}
  404.                Fill_buffer(ax);       { Folge berechnen   │}
  405.                ax:=LZBuffer[1];       { 1.Zeichen sofort  │}
  406.              END;                     { zurückgeben       │}
  407.   ELSE                                {          sonst ───┤}
  408.     BEGIN                             {   LZ steuern ───┐ │}
  409.       IF (CHAR(Lo(ax))='s')           { Eingabe "s"   ─┐│ │}
  410.         then LZ_typ:=s                { Singeleline   <┘│ │}
  411.       ELSE IF (CHAR(Lo(ax))='d')      { Eingabe "d"   ─┐│ │}
  412.         then LZ_TYP:=d                { Doubleline    <┘│ │}
  413.       ELSE IF (CHAR(Lo(ax))='p')      { Eingabe "p"   ─┐│ │}
  414.         then LZ_TYP:=p                { Pointline     <┘│ │}
  415.       ELSE IF (CHAR(Lo(ax))='u')      { Eingabe "u"   ─┐│ │}
  416.         then LZ_TYP:=n                { Dashedline    <┘│ │}
  417.       ELSE IF ax=ins then             { Eingabe "ins" ─┐│ │}
  418.         insert_on:=NOT insert_on      {               <┘│ │}
  419.       ELSE                            { sonst           │ │}
  420.         write_false_key;              { Taste verboten  │ │}
  421.       ax:=$00;                        { Nix zurückgeben │ │}
  422.       write_LZ;                       { Status ausgeben │ │}
  423.     END;{elsecase}                  {                ───┘ │}
  424.   END; {case}                       {                  ───┘}
  425. END;
  426.  
  427. PROCEDURE Int16_LZ
  428.              (Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP :WORD);
  429. {╔════════════════════════════════════════════════════════╗}
  430. {║Neuer Tastaturinterrupt  mit drei Funktionen:           ║}
  431. {║                                 -1- Hotkeywächter      ║}
  432. {║                                 -2- Linienzeichner     ║}
  433. {║                                 -3- Installationscheck ║}
  434. {║ Diese Routine wartet auf den Hotkey, um den Linien-    ║}
  435. {║ zeichner dann an- oder abzuschalten.                   ║}
  436. {║ Es löscht/Schreibt die Anzeige "LZ"                    ║}
  437. {║ Die Variable LZ_on_off steuert den Interrupt:          ║}
  438. {║                     0: Linienzeichner Wartestellung    ║}
  439. {║                     1: Interpreter aktiv               ║}
  440. {║                     2: Puffer-Ausgabefunktion aktiv    ║}
  441. {║                                                        ║}
  442. {║ Eine neue Unterfunktion  Hi(ax):=$F0 liefert in AX die ║}
  443. {║ Versionskennung und verhindert so Doppelinstallation.  ║}
  444. {╚════════════════════════════════════════════════════════╝}
  445.   INTERRUPT;
  446.  
  447. BEGIN
  448. { Unterfunktionen: Das laufende Programm liest ein Zeichen }
  449.   IF (Hi(AX)=$0) OR           { Keyboard Read für alle PCs }
  450.      (Hi(AX)=$A)              { Extended Read PC-AT MF-2   }
  451.                    { muß für MS-DOS ab 4 abgefangen werden }
  452.   THEN
  453.     BEGIN
  454.       AX := KeyFromOldInt16;      { immer Tastencode holen }
  455.                                   {  Fallunterscheidung═══╗}
  456.       IF AX =  Softkey THEN BEGIN { Hotkey gefunden       ║}
  457.         Toggle_LZ;                { Ein bzw. Ausschalten  ║}
  458.         ax:=$00;                  { nix zurückgeben       ║}
  459.       END                         {                       ║}
  460.       ELSE BEGIN                  {              sonst ═══╣}
  461.         IF LZ_on_off=1 THEN       { wenn LZ im KBD-Modus  ║}
  462.           LZ_function(ax);        { Taste interpretieren  ║}
  463.         IF LZ_on_off=2 then       { Wenn LZ im Out-Modus  ║}
  464.           Write_buffer_to_kbd;    { nächstes Zeichen      ║}
  465.                                   { in den Tastaturpuffer ║}
  466.       END;                        { ende Tastenanalyse  ══╝}
  467.     END {IF-Readkeyboard}
  468. { Unterfunktionen:    Zusatzfunktion zum Installationstest }
  469.   ELSE IF (Hi(AX)=$f0) THEN
  470.     ax:=kennung
  471. { alle restlichen Unterfunktionen }
  472.   ELSE
  473.     ExitOldInt16
  474. END;
  475.  
  476. (**********************************************************)
  477. (* Installationsteil:     Parameter interpretieren        *)
  478. (*                        Adressen ermitteln              *)
  479. (*                        Interruptvektoren sichern       *)
  480. (*                        resident beenden                *)
  481. (**********************************************************)
  482.  
  483. PROCEDURE give_syntax;
  484. VAR d:TEXT;
  485.     zeile:STRING[80];
  486. BEGIN
  487.   Assign(d,'LZ.txt'); Reset(d);
  488.   REPEAT
  489.     ReadLn(d,zeile);
  490.   UNTIL (Pos('≡',zeile)<>0);
  491.   WHILE NOT Eof(d) DO BEGIN
  492.     ReadLn(d,zeile);
  493.     WriteLn(zeile);
  494.   END;
  495.   HALT;
  496. END;
  497.  
  498. PROCEDURE give_logo;
  499. VAR d:TEXT;
  500.     zeile:STRING[80];
  501. BEGIN
  502.   Assign(d,'LZ.txt'); Reset(d);
  503.   repeat
  504.     ReadLn(d,zeile);
  505.     WriteLn(zeile);
  506.   until (Pos('¢',zeile)<>0);
  507. HALT;
  508. END;
  509.  
  510. PROCEDURE paramcheck;
  511. VAR s:STRING[10];
  512.     retcode:INTEGER;
  513.     d:TEXT;
  514.     zeile:STRING[80];
  515. BEGIN
  516.   FOR i:=1 TO ParamCount DO BEGIN
  517.     s:=ParamStr(i);
  518.     zeile:='';
  519.     IF (Pos('?',s)=1)  OR (Pos('h',s)=1)  OR (Pos('H',s)=1) THEN
  520.       give_logo;
  521.     IF Length(s)<3 THEN give_syntax;
  522.     IF (Pos('c',s)=1) OR (Pos('C',s)=1) THEN BEGIN
  523.       Assign(d,'LZ.txt'); Reset(d);
  524.       REPEAT
  525.         ReadLn(d,zeile);
  526.       UNTIL (Pos('¢',zeile)<>0);
  527.       WHILE (Pos('≡',zeile)=0) DO BEGIN
  528.         WriteLn(zeile);
  529.         ReadLn(d,zeile);
  530.       END;
  531.       HALT;    END
  532.     ELSE IF (Pos('x',s)=1)  OR (Pos('X',s)=1)THEN BEGIN
  533.       Move(s[3],s[1],Length(s)-2); s[0]:=CHAR(Length(s)-2);
  534.       Val(s,x,retcode);
  535.       IF retcode = 0 THEN
  536.         xout:=x
  537.       ELSE
  538.         give_syntax
  539.       END
  540.     ELSE IF (Pos('y',s)=1)  OR (Pos('Y',s)=1)THEN BEGIN
  541.       Move(s[3],s[1],Length(s)-2); s[0]:=CHAR(Length(s)-2);
  542.       Val(s,y,retcode);
  543.       IF retcode = 0 THEN
  544.         yout:=y
  545.       ELSE
  546.         give_syntax
  547.       END
  548.     ELSE IF (Pos('s',s)=1)  OR (Pos('S',s)=1)THEN BEGIN
  549.       Move(s[3],s[1],Length(s)-2); s[0]:=CHAR(Length(s)-2);
  550.       tasten_string:=s; END
  551.     ELSE IF (Pos('k',s)=1)  OR (Pos('K',s)=1)THEN BEGIN
  552.       Move(s[3],s[1],Length(s)-2); s[0]:=CHAR(Length(s)-2);
  553.       Val(s,code,retcode);
  554.       IF retcode = 0 THEN
  555.         IF code>255 THEN
  556.           softkey:=code
  557.         ELSE
  558.           softkey:=code SHL 8
  559.       ELSE
  560.         give_syntax;
  561.       END
  562.     ELSE
  563.       give_syntax;
  564.   END;
  565. END;
  566.  
  567. PROCEDURE MakeResident;
  568. BEGIN
  569.   IF Lo(LastMode) = 7 THEN SCR_Segment := Ptr($B000,$0000)
  570.                       ELSE SCR_Segment := Ptr($B800,$0000);
  571.   GetIntVec ($16, int16save);
  572.   SetIntVec ($16, @Int16_LZ);
  573.   Keep (0);
  574. END;
  575.  
  576. BEGIN
  577.   IF ParamCount<>0 THEN
  578.     paramcheck;
  579.   regs.AH:=$f0;  Intr($16,Regs);     { schon installiert ? }
  580.   IF regs.ax=kennung THEN
  581.     give_logo;
  582.   WriteLn(' LZ  vom ',datum);
  583.   WriteLn(' ',tasten_string,' startet/beendet die Routine');
  584.   MakeResident;                 { Resident beenden         }
  585. END.
  586. (* ------------------------------------------------------ *)
  587. (*                   Ende von LZ.PAS                      *)
  588.