home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 552.TNL7C.C < prev    next >
Text File  |  1988-05-14  |  20KB  |  539 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7C, Hostinterface                             */
  22. /* Version 1.01                                     */
  23. /* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig         */
  24. /* 02-APR-88                                     */
  25.  
  26. # include "tndef.h"        /* Definition von Konstanten             */
  27. # include "tntyp.h"        /* Definition der Typen                 */
  28. # include "tnl7ce.h"        /* externe Definitionen                 */
  29.  
  30. /*---------------------------------------------------------------------------*/
  31. VOID hosini()            /* Hostinterface initialisieren             */
  32.   {
  33.   hstusr = &hstubl[0];        /* Pointer auf Kontrollblock setzen         */
  34.  
  35.   hstusr->conflg =        /* Host ist nicht connected             */
  36.   hstusr->disflg =        /* kein Disconnect nach Info-senden         */
  37.   hstusr->inlin =        /* keine Zeilen von Eingabe da             */
  38.   hstusr->outlin =        /* keine Zeilen fuer Ausgabe da             */
  39.   blixfl =            /* Host darf nicht connected werden         */
  40.   hostco =            /* Host darf nicht connected werden         */
  41.   blicnt = 0;            /* Eingabezeile ist leer                  */
  42.  
  43.   inithd(&hstusr->inbuf);    /* Listenkopf Eingabepuffer initialisieren   */
  44.   inithd(&hstusr->outbuf);    /* Listenkopf Ausgabepuffer initialisieren   */
  45.  
  46.   magicn = 0x4d5a;        /* Flag fuer Warmstart setzen             */
  47.   }
  48.  
  49. /*---------------------------------------------------------------------------*/
  50. VOID hostsv()            /* Hostinterface Service             */
  51.   {                /* regelmaessig von MAIN aufgerufen         */
  52.   char    zeichen;        /* Scratch fuer Eingabehandling             */
  53.   mhtyp *mbuff;            /* Messagebuffer                 */
  54.  
  55.   hstusr = &hstubl[0];        /* Pointer auf Kontrollblock setzen         */
  56.   hstsen(0);            /* falls Info vorhanden: senden, wenn Platz  */
  57.   if (((hstusr->disflg & 0x80) != 0) /* Disconnect gefordert?             */
  58.      && (hstusr->outlin == 0))    /* und Info gesendet?                 */
  59.      hstdis();            /* dann disconnecten                 */
  60.  
  61.   if (! blicnt && ! blixfl) {    /* Zeile leer und kein X-OFF gekommen?         */
  62.                 /* dann Ausgabe versuchen             */
  63.  
  64.     while (! ishput() && hstusr->outlin != 0)    /* SIO frei und was da?         */
  65.      {
  66.       mbuff = (mhtyp *) unlink(hstusr->outbuf.lnext);    /*Buffer aus Kette   */
  67.       hstusr->outlin -=1;            /* eine Zeile weniger         */
  68.       while (mbuff->getcnt < mbuff->putcnt)    /* Info ausgeben         */
  69.        {
  70.         zeichen = (getchr(mbuff) &0x7f);    /* Zeichen holen         */
  71.         if (zeichen == 0x7f) zeichen = 0x08;    /* RUBOUT wird Backspace     */
  72.  
  73.         if ((zeichen >= ' ') || (zeichen == 0x0a) ||
  74.           (zeichen == 0x07) || (zeichen == 0x09))
  75.           hputc(zeichen);            /* druckbare Zeichen ausgeben*/
  76.  
  77.         else
  78.          {
  79.           if (zeichen == 0x0d)
  80.            {
  81.             hputc(zeichen);            /* CR wird CR-LF         */
  82.             hputc(0x0a);
  83.            }
  84.           else                    /* andere Kontrollzeichen    */
  85.            {
  86.             hputc('^');                /* mit Prefix             */
  87.             hputc(zeichen + '@');
  88.            }
  89.          }
  90.        }
  91.       dealmb(mbuff);        /* Buffer freigeben                 */
  92.       }
  93.     }
  94.   if (ishget() == 1) {        /* Zeichen von Eingabe bereit?             */
  95.     zeichen = hgetc() & 0x7f;    /* dann holen, ohne Parity             */
  96.     if (! blicnt)        /* erstes Zeichen der Zeile?             */
  97.       blipoi = bline;        /* Pointer auf Anfang setzen             */
  98.  
  99.     switch(zeichen) {
  100.  
  101. /*==============================*/
  102.     case 0x0d:            /* Ende der Zeile                 */
  103.       hputc(zeichen);        /* Echo fuer <CR>                 */
  104.       hputc(0x0a);        /* <LF> anhaengen                 */
  105.       blipoi = bline;        /* Pointer auf Anfang fuer Verarbeitung         */
  106.  
  107.       if ((blicnt != 0)        /* etwas eingegeben?                 */
  108.         && (*blipoi == defESC))    /* und erstes Zeichen = <ESC>? dann Befehl   */
  109.         {
  110.           ++blipoi;        /* erstes Zeichen ist verarbeitet         */
  111.           --blicnt;        /* Zahl der Zeichen -1                 */
  112.           hstcmd();        /* Befehl verarbeiten                 */
  113.         }
  114.  
  115.       else            /* Zeile kein Befehl:                 */
  116.         {
  117.           if ((hstusr->conflg != 0) /* Host connected?                 */
  118.             && ((nmbfre > 64)    /* noch Platz im Speicher?             */
  119.             &&  ((hstusr->disflg & 0x80) == 0)))   /* kein DISC eingeleitet? */
  120.             {
  121.                   mbuff = (mhtyp *) allocb();    /* Buffer holen                 */
  122.                   while (blicnt--)    /* Zeile uebertragen             */
  123.                     putchr(*blipoi++, mbuff);
  124.                   putchr('\15', mbuff);/* <CR> anhaengen             */
  125.                   rwndmb(mbuff);    /* alle Bufferpointer wieder auf 0   */
  126.                   relink(mbuff, hstusr->inbuf.lprev); /* in Kette haengen    */
  127.                   ++hstusr->inlin;    /* Zahl der Zeilen +1             */
  128.             }
  129.         }
  130.       blicnt = 0;
  131.       break;
  132.  
  133. /*==============================*/
  134.     case 0x08:            /* Backspace                     */
  135.     case 0x7f:            /* Rubout                     */
  136.       if (blicnt != 0) bliloe(); /* Zeichen loeschen - wenn vorhanden         */
  137.       break;
  138.  
  139. /*==============================*/
  140.     case 0x15:            /* ctl-u = Zeile loeschen             */
  141.     case 0x18:            /* ctl-x = Zeile loeschen             */
  142.       while (blicnt != 0) bliloe(); /* alles killen                 */
  143.       break;
  144.  
  145. /*==============================*/
  146.     case 0x11:            /* X-ON                         */
  147.       blixfl = FALSE;
  148.       break;
  149.  
  150. /*==============================*/
  151.     case 0x13:            /* X-OFF                     */
  152.       blixfl = TRUE;
  153.       break;
  154.  
  155. /*==============================*/
  156.     default:            /* sonstiges Zeichen                 */
  157.       if (blicnt < 255) {    /* noch Platz in der Zeile?             */
  158.         blieco(zeichen);    /* Echo ausgeben                 */
  159.         *blipoi++ = zeichen;    /* Zeichen in Buffer                 */
  160.         ++blicnt;        /* Zeilenlaenge zaehlen                 */
  161.         }
  162.       else hputc(0x07);        /* kein Platz: meckern!                 */
  163.  
  164.       break;
  165.       }
  166.     }
  167.   }
  168.  
  169. /*---------------------------------------------------------------------------*/
  170. VOID hostim()            /* Host Timerservice                 */
  171.   {                /* Aufruf jede Sekunde von MAIN             */
  172.   hstusr = &hstubl[0];        /* Pointer auf Userblock setzen             */
  173.   if (hstusr->conflg != 0)    /* wenn Host connected                 */
  174.     {
  175.       if ((hstusr->noact2 != 0)    /* und Timeout noch nicht 0             */
  176.         && (--hstusr->noact2 == 0)) /* Timeout runterzaehlen             */
  177.         hstdis();        /* bei 0 abwerfen                 */
  178.     }
  179.   }
  180.  
  181. /*---------------------------------------------------------------------------*/
  182. VOID hstreq()            /* Connect Request an Host             */
  183.   {
  184.   if (hostco == 1) hstcon();    /* ausfuehren, wenn erlaubt             */
  185.   else {            /* sonst anklopfen                 */
  186.     bstrng("\015\012CONNECT REQUEST fm ");
  187.     bcalou(hstusr->call);    /* Call melden                     */
  188.     bbel();            /* bimmeln                     */
  189.     l2tol7(3, hstusr, 0);    /* mit DM nach unten melden             */
  190.     }
  191.   }
  192.  
  193. /*---------------------------------------------------------------------------*/
  194. VOID hstout()            /* Host Interface Timeout             */
  195.   {
  196.   dealml(& hstusr->inbuf);    /* eingegebene Zeilen loeschen             */
  197.   hstusr->inlin = 0;
  198.   hstusr->disflg |= 0x80;    /* Abwurf verlangen                 */
  199.   }
  200.  
  201. /*---------------------------------------------------------------------------*/
  202. BOOLEAN hstrec(conflg, ublk)    /* Info fuer Host zeigen             */
  203. mhtyp    *ublk;            /* User Kontroll Block                 */
  204. BOOLEAN    conflg;            /* Congestion Flag                 */
  205.   {
  206.   hustyp *cblk;            /* lokaler Kontrollblock             */
  207.  
  208.   cblk = (hustyp *) ublk->l2lnk;        /* auf Host-Kontollblock     */
  209.  
  210.   if ((conflg == 1) || (cblk->outlin < conctl)) /* noch Platz ?             */
  211.     {
  212.       relink(unlink(ublk), cblk->outbuf.lprev); /* Buffer umhaengen         */
  213.       ++cblk->outlin;        /* eine Zeile mehr                 */
  214.       cblk->noact2 = ininat;    /* Timeout neu setzen                 */
  215.       return (TRUE);        /* OK, Info ist auf dem Weg             */
  216.     }
  217.   else return (FALSE);        /* Fehler, hat nicht funktioniert         */
  218.   }
  219.  
  220. /*---------------------------------------------------------------------------*/
  221. VOID blieco(zeichen)        /* Echo fuer Hostterminal              */
  222. char    zeichen;
  223.   {
  224.   if (blicnt == 0 && zeichen == defESC) /* erstes Zeichen und <ESC>?         */
  225.     bstrng("* ");        /* dann * als Echo                 */
  226.  
  227.   else {            /* alle anderen Zeichen                 */
  228.     if (zeichen >= ' ' || zeichen == 0x07) /* druckbar oder BELL?         */
  229.       hputc(zeichen);        /* dann Echo                     */
  230.  
  231.     else {            /* sonstige Kontrolzeichen             */
  232.       hputc('^');        /* Prefix                     */
  233.       hputc(zeichen + '@');    /* Zeichen - druckbar gemacht             */
  234.       }
  235.     }
  236.   }
  237.  
  238. /*---------------------------------------------------------------------------*/
  239. VOID bliloe()            /* 1 Zeichen am Hostterminal loeschen         */
  240.   {
  241.   char    zeichen;        /* Scratch                     */
  242.  
  243.   if ((zeichen = *(--blipoi)) != 0x07) { /* Sonderfall BELL             */
  244.     bputbs();            /* Zeichen loeschen                 */
  245.     if (zeichen < ' ') bputbs();/* Controlzeichen: Prefix + Zeichen loeschen */
  246.     }
  247.   else hputc(zeichen);        /* BELL wird wiederholt                 */
  248.  
  249.   --blicnt;            /* Zeilenlaenge -1                 */
  250.   }
  251.  
  252. /*---------------------------------------------------------------------------*/
  253. VOID bputbs()            /* Backspace an Hostterminal             */
  254.   {
  255.   bstrng("\010 \010");        /* Backspace soll destruktiv sein         */
  256.   }
  257.  
  258. /*---------------------------------------------------------------------------*/
  259. VOID hstcmd()            /* Befehl an Hostinterface ausfuehren         */
  260.   {
  261.   char       *paspoi;        /* Pointer in Passwort (<ESC>-P)         */
  262.   char       zeichen;        /* Scratch                     */
  263.   unsigned arg;            /* Argument des Befehls                 */
  264.   unsigned cnt;            /* Scratch                     */
  265.  
  266.   skipsp(&blicnt, &blipoi);    /* Leerzeichen am Anfang uebergehen         */
  267.   if (blicnt != 0) {        /* ueberhaupt was da?                 */
  268.     zeichen = upcase(*blipoi++);/* Befehl - erstes Zeichen - holen         */
  269.     --blicnt;            /* ein Zeichen ist verbraucht             */
  270.  
  271.     skipsp(&blicnt, &blipoi);    /* Rest bis zum Argument ueberlesen         */
  272.     switch(zeichen) {
  273.  
  274. /*==============================*/
  275.       case 'C':            /* Host an TNC connecten             */
  276.         if (hstusr->conflg == 0) { /* schon connected? Dann uebergehen         */
  277.           cpyid(hstusr->call, myid);    /* Host ist am TNC             */
  278.           hstcon();        /* an alle melden                 */
  279.           }
  280.         break;
  281.  
  282. /*==============================*/
  283.       case 'D':            /* Host vom TNC disconnecten             */
  284.         if (hstusr->conflg != 0) { /* schon disconnected? Dann uebergehen    */
  285.           hstsen(1);        /* an alle melden, sofort alles senden         */
  286.           hstdis();        /* Interface trennen, melden             */
  287.           }
  288.         break;
  289.  
  290. /*==============================*/
  291.       case 'P':            /* Passwort zeigen-eingeben             */
  292.         if (blicnt == 0) {    /* ohne Argument = zeigen             */
  293.           bpromp();        /* neue Zeile, *                 */
  294.           paspoi = paswrd;    /* auf Anfang des Passwortes             */
  295.           for (cnt = 0; cnt < paswle; ++cnt)
  296.             bchout(*paspoi++);    /* Passwort ausgeben                 */
  297.           bende();        /* und * am Ende                 */
  298.           }
  299.  
  300.         else {            /* neues Passwort setzen             */
  301.           paspoi = paswrd;    /* auf Anfang Passwort                 */
  302.           paswle =        /* Laenge = 0                     */
  303.           cnt = 0;        /* eingegebene Zeichen = 0             */
  304.  
  305.           while (blicnt-- != 0) { /* Rest der Zeile ist Passwort         */
  306.             if ((zeichen = *blipoi++) != 0x0a) { /* Linefeed ueberlesen         */
  307.               if ((*paspoi++ = zeichen) != ' ') /* Leerzeichen zaehlen nicht */
  308.                 ++cnt;
  309.               ++paswle;
  310.               if (paswle == 80)
  311.                 break;        /* maximale Laenge erreicht?             */
  312.               }
  313.             }
  314.           if (cnt < 5)
  315.             paswle = 0;        /* Mindestlaenge muss eingehalten werden     */
  316.           }
  317.         break;
  318.  
  319. /*==============================*/
  320.       case 'T':            /* Keyup Delay zeigen-eingeben             */
  321.         if (blicnt == 0)    /* ohne Argument = zeigen             */
  322.           bnuout(Tpar);
  323.  
  324.         else {            /* mit Argument = setzen             */
  325.           if ((arg = nxtnum(&blicnt, &blipoi)) <= 255) /* holen, testen         */
  326.             Tpar = arg;        /* ok, merken                     */
  327.           else
  328.             invcmd();        /* meckern                     */
  329.           }
  330.         break;
  331.  
  332. /*==============================*/
  333.       case 'Y':            /* Connect zu Host erlaubt j-n             */
  334.         if (blicnt == 0)    /* ohne Argument = zeigen             */
  335.           bnuout(hostco);
  336.  
  337.         else {            /* mit Argument = setzen             */
  338.           if ((arg = nxtnum(&blicnt, &blipoi)) <= 1) /* holen, testen         */
  339.             hostco = arg;    /* ok, merken                     */
  340.           else
  341.             invcmd();        /* meckern                     */
  342.           }
  343.         break;
  344.  
  345. /*==============================*/
  346.       case 'F':            /* Full-Duplex j-n                 */
  347.         if (blicnt == 0)    /* ohne Argument = zeigen             */
  348.           bnuout(Dpar);
  349.  
  350.         else            /* mit Argument = setzen             */
  351.          {
  352.           if ((arg = nxtnum(&blicnt, &blipoi)) <= 1)    /* holen, testen     */
  353.            {
  354.             if ((Dpar == FALSE) && (arg == TRUE))
  355.              {                        /* Wechsel auf Full  */
  356.               DIinc();                    /* Interrupts aus    */
  357.               Dpar = TRUE;
  358.               pushtx();                    /* Sender anwerfen   */
  359.               DECei();                    /* Interrupts an     */
  360.              }
  361.             Dpar = arg;        /* ok, merken                     */
  362.            }
  363.           else
  364.             invcmd();        /* meckern                     */
  365.           }
  366.         break;
  367.  
  368. /*==============================*/
  369.       default :            /* ungueltiger Befehl                 */
  370.         invcmd();        /* meckern                     */
  371.         break;
  372.  
  373.       }
  374.     }
  375.   }
  376.  
  377. /*---------------------------------------------------------------------------*/
  378. VOID hstcon()            /* Host wird connected                 */
  379.   {
  380.   bstrng("\015\012CONNECTED to ");
  381.   bcalou(hstusr->call);        /* Meldung mit Call und Bimmel             */
  382.   bbel();
  383.  
  384.   l2tol7(1, hstusr, 0);        /* nach unten melden: Usrtyp, ctrl-blk, cmd  */
  385.  
  386.   hstusr->conflg = 1;        /* Connect Flag setzen                 */
  387.   hstusr->noact2 = ininat;    /* no-activity-timeout neu setzen         */
  388.   }
  389.  
  390. /*---------------------------------------------------------------------------*/
  391. VOID hstdis()            /* Host wird disconnected             */
  392.   {
  393.   dealml(& hstusr->inbuf);    /* Eingabebuffer freigeben             */
  394.   dealml(& hstusr->outbuf);    /* Ausgabebuffer freigeben             */
  395.   hstusr->inlin =        /* keine Zeile in Eingabe             */
  396.   hstusr->outlin = 0;        /* keine Zeile in Ausgabe             */
  397.  
  398.   bstrng("\015\012DISCONNECTED fm ");
  399.   bcalou(hstusr->call);        /* Meldung mit Call und Bimmel             */
  400.   bbel();
  401.  
  402.   l2tol7(2, hstusr, 0);        /* nach unten melden: Usrtyp, ctrl-blk, cmd  */
  403.  
  404.   hstusr->conflg =        /* Connect Flag ruecksetzen             */
  405.   hstusr->disflg = 0;        /* Abwurf ausgefuehrt markieren             */
  406.   }
  407.  
  408. /*---------------------------------------------------------------------------*/
  409. VOID hstsen(conflg)        /* Host Sende Service                 */
  410. BOOLEAN conflg;            /* Congestion Flag, 0=normal, 1=alles sofort */
  411.   {
  412. mhtyp    *mbhd;            /* Message Buffer Head der Info             */
  413.  
  414.   while (hstusr->inlin != 0)    /* solange Zeilen vorhanden             */
  415.     {
  416.       mbhd = (mhtyp *) hstusr->inbuf.lnext;    /* MBHD aufbauen                 */
  417.       mbhd->l2lnk = (l2ltyp *) hstusr;    /* User ist Host                 */
  418.       mbhd->usrtyp = 0;        /* Usertyp setzen                 */
  419.       if (! fmlink(conflg, mbhd)) /* Frame senden, Fehler dabei?         */
  420.         break;            /* im Fehlerfalle Abbruch             */
  421.       hstusr->inlin -=1;    /* eine Zeile erledigt                 */
  422.       hstusr->noact2 = ininat;    /* no-activity-timeout neu setzen         */
  423.     }
  424.   }
  425.  
  426. /*---------------------------------------------------------------------------*/
  427. VOID invcmd()            /* ungueltigen Befehl melden             */
  428.   {
  429.   bpromp();            /* am Anfang ein *                 */
  430.   bstrng("INVALID COMMAND");    /* meckern                     */
  431.   belend();            /* bimmeln und einen *                 */
  432.   }
  433.  
  434. /*---------------------------------------------------------------------------*/
  435. VOID bcalou (call)              /* Call auf Crosslink Kanal geben         */
  436. char *call;
  437.  
  438.   {
  439.   char     ssid;            /* SSID des Calls             */
  440.   char     zeichen;            /* aktuelles Zeichen             */
  441.   unsigned z_zahl;            /* Anzahl ausgegebener Zeichen          */
  442.  
  443.   for (z_zahl = 0; z_zahl < 6; ++z_zahl)
  444.     {
  445.       zeichen = *call++;
  446.       if (zeichen != ' ') bchout(zeichen);
  447.     }
  448.   ssid = (*call >> 1) & 0x0f;
  449.   if (ssid)
  450.     {
  451.       hputc('-');
  452.       bnumou(ssid);
  453.     }
  454.   }
  455.  
  456. /*---------------------------------------------------------------------------*/
  457. VOID bnuout (zahl)              /* Zahl auf Crosslink Kanal geben         */
  458. int zahl;            /* eingerahmt in * *                 */
  459.  
  460.   {
  461.   bpromp();            /* neue Zeile, *                 */
  462.   bnumou(zahl);            /* Zahl                         */
  463.   bende();            /* und * am Ende                 */
  464.   }
  465.  
  466. /*---------------------------------------------------------------------------*/
  467. VOID bnumou (zahl)              /* Zahl auf Crosslink Kanal geben         */
  468. unsigned zahl;
  469.  
  470.   {
  471.   BOOLEAN  notnul;        /* fuehrende Null j/n                 */
  472.   unsigned diviso;        /* Stellenwert der aktuellen Stelle         */
  473.   unsigned ziffer;        /* aktuelle Ziffer                 */
  474.   unsigned numcnt;        /* Zahl der ausgegebenen Ziffern         */
  475.  
  476.   notnul = FALSE;
  477.   diviso = 10000;
  478.   for(numcnt = 0; numcnt < 5; ++numcnt) {
  479.     ziffer = zahl / diviso;
  480.     if ((ziffer != 0) || (notnul == TRUE) || (diviso == 1)) {
  481.       hputc (ziffer + '0');
  482.       notnul = TRUE;
  483.       }
  484.     zahl %= diviso;
  485.     diviso /= 10;
  486.     }
  487.   }
  488.  
  489. /*---------------------------------------------------------------------------*/
  490. VOID bpromp()                   /* Prompt auf Crosslink Kanal             */
  491.   {
  492.   bstrng("* ");
  493.   }
  494.  
  495. /*---------------------------------------------------------------------------*/
  496. VOID bende()                    /* Ende Kennung auf Crosslink Kanal         */
  497.   {
  498.   bstrng(" *\015\12");
  499.   }
  500.  
  501. /*---------------------------------------------------------------------------*/
  502. VOID belend()                   /* Ende mit BELL auf Crosslink Kanal         */
  503.   {
  504.   bstrng(" *\007\015\012");
  505.   }
  506.  
  507. /*---------------------------------------------------------------------------*/
  508. VOID bbel()                     /* BELL Ausgabe auf Crosslink Kanal         */
  509.   {
  510.   bstrng("\015\012\007");
  511.   }
  512.  
  513. /*---------------------------------------------------------------------------*/
  514. VOID bstrng (string)            /* String auf Crossllink Kanal geben         */
  515. char *string;
  516.   {
  517.   while (*string != 0) hputc(*string++);
  518.   }
  519.  
  520. /*---------------------------------------------------------------------------*/
  521. VOID bchout (c)                 /* Zeichen auf Crosslink Kanal geben         */
  522. char c;
  523.   {
  524.   if (c >= ' ') hputc(c);
  525.   else {
  526.     hputc('^');
  527.     hputc(c + '@');
  528.     }
  529.   }
  530.  
  531. /*---------------------------------------------------------------------------*/
  532. BOOLEAN iswarm ()                   /* Test auf Warmstart             */
  533.   {
  534.   return (magicn == 0x4d5a);    /* RAM noch intakt? dann Warmstart         */
  535.   }
  536.  
  537. /*--- Ende Level 7c ---------------------------------------------------------*/
  538.  
  539.