home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 526.L2D.C < prev    next >
Text File  |  1988-05-14  |  51KB  |  1,137 lines

  1. /**************************************************************************\
  2. *                                                                          *
  3. *                                                                          *
  4. *    *****                      *****                                      *
  5. *      *****                  *****                                        *
  6. *        *****              *****                                          *
  7. *          *****          *****                                            *
  8. *            *****      *****                                              *
  9. *              *****  *****                                                *
  10. *            *****      *****                                              *
  11. *          *****          *****          The Firmware. The Net.            *
  12. *        *****              *****        Portable. Compatible.             *
  13. *      *****                  *****      Public Domain.                    *
  14. *    *****                      *****    By NORD><LINK.                    *
  15. *                                                                          *
  16. *                                                                          *
  17. *                                                                          *
  18. *    L2D.C   -   Level 2, Teil 4, zeitkritische Routinen                   *
  19. *                                                                          *
  20. *                Achtung: Ronner nicht auf diesen Code anwenden !          *
  21. *                                                                          *
  22. *                                                                          *
  23. *    angelegt:      DC4OX                                                  *
  24. *    modifiziert:                                                          *
  25. *                                                                          *
  26. \**************************************************************************/
  27.  
  28.  
  29.  
  30. /* #define PORTABLE */        /* nicht portabler Code, einige Routinen,   */
  31.                               /* die einzigen laengeren Routinen, die aus */
  32.                               /* Interrupts heraus aufgerufen werden,     */
  33.                               /* werden assemberoptimiert (#asm/#endasm)  */
  34.  
  35.  
  36.  
  37.  
  38.  
  39. /*                                                             Includes   */
  40. /**************************************************************************/
  41.  
  42. #include "all.h"         /* allgemeine Festlegungen                       */
  43. #include "l2.h"          /* Festlegungen/Datenstrukturen fuer den Level 2 */
  44.  
  45.  
  46.  
  47.  
  48.  
  49. /*                                                            Externals   */
  50. /**************************************************************************/
  51. /* nicht aus L2EXT.H, da bei #asm-Deklarationen nicht wie vom C-Compiler  */
  52. /* sonst automatisch die doppelten Definitionen geloescht werden !        */
  53.  
  54. extern             reset();
  55. extern             DIinc();
  56. extern             decEI();
  57. extern unsigned    nmbfre;
  58. extern LHEAD       freel;
  59. extern LHEAD       rxfl;
  60. extern LHEAD       stfl;
  61. extern LHEAD       trfl;
  62. extern LHEAD       txl2fl[];
  63. extern MBHEAD     *rxfhd[];
  64. extern MBHEAD     *txfhd[];
  65.  
  66. #ifdef PORTABLE
  67. extern LEHEAD     *allocb();
  68. extern LEHEAD     *unlink();
  69. extern LEHEAD     *relink();
  70. #endif
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /**************************************************************************\
  77. *                                                                          *
  78. * action      :  "level 1 put"                                             *
  79. *                                                                          *
  80. *                Je nach action Zeichen in den aktiven RX-Framebuffer      *
  81. *                schreiben, RX-Framebuffer auf den Muell werfen, oder      *
  82. *                RX-Framebuffer in RX-Frameliste einhaengen.               *
  83. *                                                                          *
  84.  **************************************************************************
  85. *                                                                          *
  86. * parameter   :  action  -                                                 *
  87. *                                                                          *
  88. *                  7  6543210 7654321  0                                   *
  89. *                +---+-------+-------+---+  RX-Framebuffer in RX-          *
  90. *                | 1 |  port |       | 0 |  Frameliste einhaengen,         *
  91. *                +---+-------+-------+---+  return NO                      *
  92. *                                                                          *
  93. *                +---+-------+-------+---+  falls RX-Framebuffer angelegt, *
  94. *                | 1 |  port |       | 1 |  diesen auf den Muell werfen    *
  95. *                +---+-------+-------+---+  (neuen beginnen), return NO    *
  96. *                                                                          *
  97. *                +---+-------+-----------+  Zeichen ch in aktiven RX-      *
  98. *                | 0 |  port |     ch    |  Framebuffer schreiben, ist es  *
  99. *                +---+-------+-----------+  das erste Zeichen, neuen       *
  100. *                                           RX-Framebuffer beginnen,       *
  101. *                                           entsprechend der einlaufenden  *
  102. *                                           Zeichen neue Datenbuffer       *
  103. *                                           allokieren und anhaengen,      *
  104. *                                           normal return NO, return YES,  *
  105. *                                           wenn Frame zu gross geworden   *
  106. *                                                                          *
  107. *                                           port gibt den verwendeten      *
  108. *                                           Empfangskanal an (HDLC/RS232)  *
  109. *                                                                          *
  110. * r/o globals :  -                                                         *
  111. *                                                                          *
  112. * r/w globals :  rxfhd   - Zeiger auf den Kopf des aktiven RX-Frames       *
  113. *                          0, wenn kein RX-Frame aktiv                     *
  114. *                rxfl    - Liste der empfangenen Frames                    *
  115. *                trfl    - Liste der Muell-Frames                          *
  116. *                                                                          *
  117. * locals      :  s.u.                                                      *
  118. *                                                                          *
  119. * returns     :  s.o.                                                      *
  120. *                                                                          *
  121. \**************************************************************************/
  122.  
  123. #ifdef PORTABLE
  124.  
  125. BOOLEAN l1put(action)
  126.  
  127. unsigned action;
  128.  
  129.   {
  130.     unsigned    port;         /* port aus action                          */
  131.     MBHEAD    **rxfbpp;       /* Zeiger auf Zeiger auf aktuelles RX-Frame */
  132.  
  133.     rxfbpp = &rxfhd[port = (action>>8) & 0x7F]; /* Adresse RX-Framezeiger */
  134.     if (!(action & 0x8000))                     /* Zeichen oder Befehl ?  */
  135.       {                                         /* Zeichen :              */
  136.         if (!*rxfbpp)                           /* RX-Frame aktiv ?       */
  137.           {
  138.             *rxfbpp = (MBHEAD *)allocb();       /* nein - neues anlegen   */
  139.             (*rxfbpp)->l2port = port;           /*        fuer port       */
  140.           }
  141.         putchr(action & 0xFF,*rxfbpp);          /* Zeichen in Frame       */
  142.         if ((*rxfbpp)->mbpc > L2MFLEN)          /* Framelaengencheck      */
  143.           return (YES);
  144.       }
  145.     else                                        /* Befehl :               */
  146.       if (*rxfbpp)                              /* nur wenn Frame aktiv   */
  147.         {                                       /* Befehl ausfuehren      */
  148.           relink(*rxfbpp,action & 0x0001 ? trfl.tail : rxfl.tail);
  149.           *rxfbpp = NULL;                       /* kein RX-Frame aktiv    */
  150.         }
  151.     return (NO);                                /* default return NO      */
  152.   }
  153.  
  154. #else
  155.  
  156. #asm
  157.           public l1put?         ; globales Symbol
  158.  
  159. l1put?:   call  ?ens            ; IX/BC Stackframezeiger (Funktionsparameter)
  160.           defw  -4              ; und 4 Byte lokaler Variablenspeicher
  161.           ld    A,(IX+9)        ; A = MSB(action) & 0x7F
  162.           and   127             ; (0x7F)
  163.           ld    (IX+0),A        ; port = A
  164.           add   A,A             ; rxfbpp = HL = &rxfhd[port]
  165.           ld    E,A
  166.           ld    D,0
  167.           ld    HL,rxfhd?
  168.           add   HL,DE
  169.           ld    (IX+2),L
  170.           ld    (IX+3),H
  171.           bit   7,(IX+9)        ; Befehl oder Zeichen ?
  172.           jr    NZ,?lput2       ; Befehl ...
  173.  
  174.           ld    E,(HL)          ; Zeichen, DE = *rxfbpp = rxfhd[port]
  175.           inc   HL
  176.           ld    D,(HL)
  177.           ld    A,D             ; Empfangsframe aktiv (*rxfbpp != 0) ?
  178.           or    E
  179.           jr    NZ,?lput1       ; ja   -
  180.           push  HL              ; nein - rxfbpp merken
  181.           call  allocb?         ;        Freibuffer allokieren
  182.           ex    DE,HL           ;        DE = Adresse Freibuffer
  183.           pop   HL              ;        HL = rxfbpp
  184.           ld    (HL),D          ;        *rxfbpp = Adresse Freibuffer
  185.           dec   HL
  186.           ld    (HL),E
  187.           ld    HL,18           ;        Freibuffer->l2port = port
  188.           add   HL,DE
  189.           ld    A,(IX+0)
  190.           ld    (HL),A
  191.  
  192. ?lput1:   push  DE              ; putchr(LSB(action),*rxfbpp);
  193.           ld    L,(IX+8)
  194.           push  HL
  195.           call  putchr?
  196.           pop   DE
  197.           pop   DE              ; DE = *rxfbpp
  198.           ld    HL,10           ; DE = *rxfbpp->mbpc 
  199.           add   HL,DE
  200.           ld    E,(HL)
  201.           inc   HL
  202.           ld    D,(HL)
  203.           ld    HL,328          ; DE <= L2MFLEN, Frame noch nicht zu lang ? 
  204.           or    A
  205.           sbc   HL,DE
  206.           jr    NC,?lput5       ; ja   - Frame ok, return(NO);
  207.           ld    HL,1            ; nein - Frame zu lang, return(YES);
  208.           jr    ?lput6
  209.  
  210. ?lput2:   ld    E,(HL)          ; Befehl, DE = *rxfbpp
  211.           inc   HL
  212.           ld    D,(HL)
  213.           ld    A,D             ; Empfangsframe aktiv (*rxfbpp != 0) ?
  214.           or    E
  215.           jr    Z,?lput5        ; nein - return(NO);
  216.           bit   0,(IX+8)        ; ja   - auf den Muell oder in RX-Liste ?
  217.           jr    NZ,?lput3       ; 
  218.           ld    HL,(rxfl?+2)    ; -> in RX-Liste, HL = rxfl.tail
  219.           jr    ?lput4
  220. ?lput3:   ld    HL,(trfl?+2)    ; -> auf den Muell, HL = trfl.tail
  221. ?lput4:   push  HL              ; relink(HL,*rxfbpp); (DE = *rxfbpp)
  222.           push  DE
  223.           call  relink?
  224.           pop   DE
  225.           pop   DE
  226.           ld    L,(IX+2)        ; HL = rxfbpp
  227.           ld    H,(IX+3)
  228.           xor   A
  229.           ld    (HL),A          ; *rxfbpp = 0
  230.           inc   HL
  231.           ld    (HL),A
  232. ?lput5:   ld    HL,0            ; return(NO);
  233. ?lput6:   ld    A,H
  234.           or    L
  235.           call  ?exs            ; alte Stackframezeiger einsetzen, lokalen
  236.           defw  4               ; Speicher zurueckgeben
  237. #endasm
  238.  
  239. #endif
  240.  
  241.  
  242.  
  243.  
  244.  
  245. /**************************************************************************\
  246. *                                                                          *
  247. * action      :  "level 1 get"                                             *
  248. *                                                                          *
  249. *                Sendeframebuffer verwalten. Je nach action Zeichen aus    *
  250. *                aktivem Sendeframe holen, Sendeframe rewind-en, oder      *
  251. *                alle zu sendenden Frames ohne Sendung in Gesendet-Liste   *
  252. *                umhaengen.                                                *
  253. *                Sind alle Zeichen aus einem Frame gelesen, wird es        *
  254. *                in die Gesendet-Liste umgehaengt.                         *
  255. *                                                                          *
  256.  **************************************************************************
  257. *                                                                          *
  258. * parameter   :  action  -                                                 *
  259. *                                                                          *
  260. *                  7  6543210 7654321  0                                   *
  261. *                +---+-------+-------+---+  falls ein Framebuffer TX-aktiv *
  262. *                | 1 |  port |       | 0 |  ist, diesen rewind-en, kein    *
  263. *                +---+-------+-------+---+  return-Wert                    *
  264. *                                                                          *
  265. *                +---+-------+-------+---+  aktiven Framebuffer und alle   *
  266. *                | 1 |  port |       | 1 |  zu sendenden                   *
  267. *                +---+-------+-------+---+  Frames in Gesendet-Liste       *
  268. *                                           umhaengen, kein return-Wert    *
  269. *                                                                          *
  270. *                +---+-------+-------+---+  Zeichen aus aktivem Frame      *
  271. *                | 0 |  port |       | 0 |  holen, dann return-Wert (s.u.) *
  272. *                +---+-------+-------+---+                                 *
  273. *                                                                          *
  274. *                                           Frame aktiv = haengt an txfr   *
  275. *                                                                          *
  276. *                                           port gibt den verwendeten      *
  277. *                                           Sendekanal an (HDLC/RS232)     *
  278. *                                                                          *
  279. * r/o globals :  -                                                         *
  280. *                                                                          *
  281. * r/w globals :  txfhdr  - Zeiger auf den Kopf des aktiven TX-Frames,      *
  282. *                          0, wenn kein TX-Frame aktiv                     *
  283. *                txl2fl  - Liste der zu sendenden (DWAIT) Level-2-Frames   *
  284. *                stfl    - Liste der gesendeten Frames                     *
  285. *                                                                          *
  286. * locals      :  s.u                                                       *
  287. *                                                                          *
  288. * returns     :  0x8001 - aktives Frame zuende, kein weiteren vorhanden    *
  289. *                0x8000 - aktives Frame zuende, noch weitere vorhanden     *
  290. *                0x00cc - naechstes Zeichen aus aktivem Frame              *
  291. *                                                                          *
  292. \**************************************************************************/
  293.  
  294. #ifdef PORTABLE
  295.  
  296. unsigned l1get(action)
  297.  
  298. unsigned action;
  299.  
  300.   {
  301.     unsigned    port;         /* port aus action                          */
  302.     MBHEAD    **txfbpp;       /* Zeiger auf Zeiger auf aktuelles TX-Frame */
  303.     LHEAD      *l2flp;        /* Zeiger auf DWAIT-Framelistenkopf         */
  304.  
  305.     txfbpp = &txfhd[port = (action>>8) & 0x7F]; /* Adresse TX-Framezeiger */
  306.     l2flp = &txl2fl[port];                      /* Sendeframelistenkopf   */
  307.     if (!(action & 0x8000))                     /* Zeichen oder Befehl ?  */
  308.       {                                         /* Zeichen :              */
  309.         if (!*txfbpp)                           /* wenn TX-Frame inaktiv  */
  310.           if (l2flp->head != l2flp)             /* aus der TX-Frameliste  */
  311.             unlink(*txfbpp = l2flp->head);      /* neues TX-Frame holen   */
  312.           else                                  /* sonst "keine weiteren  */
  313.             return (0x8001);                    /* Frames zu senden"      */
  314.         if ((*txfbpp)->mbgc < (*txfbpp)->mbpc)  /* wenn noch Zeichen im   */
  315.           return(getchr(*txfbpp) & 0xFF);       /* TX-Frame, eins holen   */
  316.         else 
  317.           {                                  /* sonst TX-Frame in         */
  318.             relink(*txfbpp,stfl.tail);       /* Gesendet-Liste,           */
  319.             *txfbpp = NULL;                  /* TX-Frame "inaktivieren",  */
  320.             if (l2flp->head != l2flp)        /* Status "noch Frames da /  */
  321.               return (0x8000);               /* nicht da" ermitteln und   */
  322.             return (0x8001);                 /* zurueckgeben              */
  323.           }
  324.       }
  325.     else                                     /* Befehl :                  */
  326.       if (!(action & 0x0001))                
  327.         {                                    /* wenn TX-Frame aktiv, dies */
  328.           if (*txfbpp) rwndmb(*txfbpp);      /* rewind-en                 */
  329.         }
  330.       else                                   /* alles in Gesendet-Liste   */
  331.         {
  332.           if (*txfbpp)                       /*   wenn TX-Frame aktiv     */
  333.             {                                /*   dies in Gesendet-Liste  */
  334.               relink(*txfbpp,stfl.tail);     /*   umhaengen und           */
  335.               *txfbpp = NULL;                /*   TX-Frame "inaktivieren" */
  336.             }
  337.           rlmlsl(l2flp);                     /*   def: alles gesendet !   */
  338.         }
  339.    }
  340.  
  341. #else
  342.  
  343. #asm
  344.           public l1get?         ; globales Symbol
  345.  
  346. l1get?:   call  ?ens            ; IX/BC Stackframezeiger (Funktionsparameter)
  347.           defw  -6              ; und 6 Byte lokaler Variablenspeicher
  348.           ld    A,(IX+11)       ; A = MSB(action) & 0x7F
  349.           and   127             ; (0x7F)
  350.           ld    (IX+0),A        ; port = A
  351.           add   A,A             ; txfbpp = HL = &txfhd[port];
  352.           ld    E,A
  353.           ld    D,0
  354.           ld    HL,txfhd?
  355.           add   HL,DE
  356.           ld    (IX+2),L
  357.           ld    (IX+3),H
  358.           ld    HL,txl2fl?      ; l2flp = &txl2fl[port]
  359.           add   HL,DE
  360.           add   HL,DE
  361.           ld    (IX+4),L
  362.           ld    (IX+5),H
  363.           bit   7,(IX+11)       ; Befehl oder Zeichen ?
  364.           jp    NZ,?lget5       ; Befehl ...
  365.  
  366.           ld    L,(IX+2)        ; Zeichen, HL = txfbpp
  367.           ld    H,(IX+3)
  368.           ld    E,(HL)          ; DE = *txfbpp = txfhd[port]
  369.           inc   HL
  370.           ld    D,(HL)
  371.           ld    A,D             ; Sendeframe aktiv, (*txfbpp != 0) ?
  372.           or    E
  373.           jr    NZ,?lget2       ; ja   -
  374.           push  HL              ; nein - (txfbpp merken)
  375.           ld    L,(IX+4)        ;        (HL = l2flp)
  376.           ld    H,(IX+5)        ;        (DE = l2flp->head)
  377.           ld    E,(HL)
  378.           inc   HL
  379.           ld    D,(HL)
  380.           dec   HL              ;        (Korrektur)
  381.           or    A               ;        l2flp->head == l2flp, d.h.
  382.           sbc   HL,DE           ;        TX-Frameliste leer ?
  383.           jr    NZ,?lget1
  384.           pop   HL              ;        ja   - Stack korrigieren
  385.           ld    HL,32769        ;               return(0x8001);
  386.           jp    ?lget8
  387. ?lget1:   pop   HL              ;        nein - *txfbpp = DE
  388.           ld    (HL),D          ;               (l2flp->head/diflp->head)
  389.           dec   HL
  390.           ld    (HL),E
  391.           push  DE
  392.           call  unlink?         ;               unlink(*txfbpp);
  393.           pop   DE              ;               (DE = *txfbpp)
  394.  
  395. ?lget2:   push  DE              ; (DE = *txfbpp)
  396.           push  DE
  397.           ld    HL,12           ; (push (*txfbpp)->mbgc)
  398.           add   HL,DE
  399.           ld    E,(HL)
  400.           inc   HL
  401.           ld    D,(HL)
  402.           pop   HL              ; (HL = *txfbpp)
  403.           push  DE
  404.           ld    DE,10           ; (DE = (*txfbpp)->mbpc)
  405.           add   HL,DE
  406.           ld    E,(HL)
  407.           inc   HL
  408.           ld    D,(HL)
  409.           pop   HL
  410.           or    A               ; if ((*txfbpp)->mbgc < (*txfbpp)->mbpc)
  411.           sbc   HL,DE           ;   return(getchr(*txfbpp) & 0xFF);
  412.           pop   DE              ; (DE = *txfbpp)
  413.           jr    NC,?lget3
  414.           push  DE
  415.           call  getchr?
  416.           pop   DE
  417.           ld    H,0
  418.           jp    ?lget8
  419.  
  420. ?lget3:   ld    HL,(stfl?+2)    ; else
  421.           push  HL              ;   {
  422.           push  DE              ;     relink(*txfbpp,stfl.tail);
  423.           call  relink?
  424.           pop   DE
  425.           pop   DE
  426.           ld    L,(IX+2)        ;     *txfbpp = NULL;
  427.           ld    H,(IX+3)
  428.           xor   A
  429.           ld    (HL),A
  430.           inc   HL
  431.           ld    (HL),A
  432.           ld    L,(IX+4)        ;     if (l2flp->head != l2flp)
  433.           ld    H,(IX+5)        ;       return (0x8000)
  434.           ld    E,(HL)
  435.           inc   HL
  436.           ld    D,(HL)
  437.           dec   HL
  438.           or    A
  439.           sbc   HL,DE 
  440.           ld    HL,0
  441.           jr    NZ,?lget4
  442.           inc   HL              ;     return (0x8001);
  443. ?lget4:   set   7,H             ;   }
  444.           jr    ?lget8
  445.  
  446. ?lget5:   bit   0,(IX+10)       ; Befehl, alles in Gesendet-Liste umhaengen ?
  447.           jr    NZ,?lget6
  448.           ld    L,(IX+2)        ; nein - if (*txfbpp) rwndmb(*txfbpp);
  449.           ld    H,(IX+3)
  450.           ld    E,(HL)
  451.           inc   HL
  452.           ld    D,(HL)
  453.           ld    A,D
  454.           or    E
  455.           jr    Z,?lget8
  456.           push  DE
  457.           call  rwndmb?
  458.           pop   DE
  459.           jr    ?lget8
  460. ?lget6:   ld    L,(IX+2)        ; ja - if (*txfbpp)
  461.           ld    H,(IX+3)
  462.           ld    E,(HL)
  463.           inc   HL
  464.           ld    D,(HL)
  465.           ld    A,D
  466.           or    E
  467.           jr    Z,?lget7
  468.           push  HL              ;        {
  469.           ld    HL,(stfl?+2)    ;          relink(*txfbpp,stfl.tail);
  470.           push  HL
  471.           push  DE
  472.           call  relink?
  473.           pop   DE
  474.           pop   DE
  475.           pop   HL              ;          *txfbpp = NULL;
  476.           xor   A
  477.           ld    (HL),A
  478.           dec   HL
  479.           ld    (HL),A          ;        }
  480. ?lget7:   ld    L,(IX+4)        ;      rlmlsl(l2flp);
  481.           ld    H,(IX+5)
  482.           push  HL
  483.           call  rlmlsl?
  484.           pop   DE
  485. ?lget8:   ld    A,H
  486.           or    L
  487.           call  ?exs            ; alte Stackframezeiger einsetzen, lokalen
  488.           defw  6               ; Speicher zurueckgeben
  489. #endasm
  490.  
  491. #endif
  492.  
  493.  
  494.  
  495.  
  496.  
  497. /**************************************************************************\
  498. *                                                                          *
  499. * action      :  "relink message list to sent list"                        *
  500. *                                                                          *
  501. *                Frameliste in Gesendete-Frames-Liste umhaengen.           *
  502. *                                                                          *
  503.  **************************************************************************
  504. *                                                                          *
  505. * parameter   :  mlp     - in stfl umzuhaengende Frameliste                *
  506. *                                                                          *
  507. * r/o globals :  -                                                         *
  508. *                                                                          *
  509. * r/w globals :  stfl    - Liste der schon gesendeten Frames               *
  510. *                                                                          *
  511. * locals      :  -                                                         *
  512. *                                                                          *
  513. * returns     :  -                                                         *
  514. *                                                                          *
  515. \**************************************************************************/
  516.  
  517. #ifdef PORTABLE
  518.  
  519. VOID rlmlsl(mlp)
  520.  
  521. LEHEAD *mlp;
  522.  
  523.   {
  524.     while (mlp->nextle != mlp) relink(unlink(mlp->nextle),stfl.tail);
  525.   }
  526.  
  527. #else
  528.  
  529. #asm
  530.           public rlmlsl?        ; globales Symbol
  531.  
  532. rlmlsl?:  call  ?en             ; IX setzen (Funktionsparameterzeiger)
  533. ?rlml1:   ld    L,(IX+4)        ; HL = mlp
  534.           ld    H,(IX+5)
  535.           ld    E,(HL)          ; DE = mlp->nextle
  536.           inc   HL            
  537.           ld    D,(HL)
  538.           dec   HL              ; (HL korrigieren)
  539.           or    A
  540.           sbc   HL,DE           ; mlp->nextle != mlp ?
  541.           jr    Z,?rlml2        ; nein - dann war's das
  542.           ld    HL,(stfl?+2)    ; ja   - relink(unlink(DE),stfl.tail);
  543.           push  HL
  544.           push  DE
  545.           call  unlink?
  546.           pop   DE
  547.           push  HL
  548.           call  relink?
  549.           pop   DE
  550.           pop   DE
  551.           jr    ?rlml1          ; while-Schleife
  552. ?rlml2:   pop   BC              ; Stack korrigieren
  553.           push  BC              ; Stackframepointer auf Wert vor
  554.           pop   IX              ; Aufruf
  555.           ret                   ; das war's
  556.  
  557. #endasm
  558.  
  559. #endif
  560.  
  561.  
  562.  
  563.  
  564.  
  565. /**************************************************************************\
  566. *                                                                          *
  567. * action      :  "put character"                                           *
  568. *                                                                          *
  569. *                Zeichen in Messagebuffer schreiben, Put-Counter erhoehen  *
  570. *                und Buffer-Pointer setzen. Ist der aktuelle Datenbuffer   *
  571. *                im Messagebuffer voll, dann neuen Datenbuffer allokieren  *
  572. *                und ans Datenbufferlistenende des Messagebuffers          *
  573. *                anhaengen.                                                *
  574. *                                                                          *
  575.  **************************************************************************
  576. *                                                                          *
  577. * parameter   :  ch      - in den Buffer zu schreibendes Zeichen           *
  578. *                mbhd    - Zeiger auf den Messagebuffer-Kopf, in den ch    *
  579. *                          zu schreiben ist                                *
  580. *                                                                          *
  581. * r/o globals :  -                                                         *
  582. *                                                                          *
  583. * r/w globals :  -                                                         *
  584. *                                                                          *
  585. * locals      :  -                                                         *
  586. *                                                                          *
  587. * returns     :  -                                                         *
  588. *                                                                          *
  589. \**************************************************************************/
  590.  
  591. #ifdef PORTABLE
  592.  
  593. VOID putchr(ch,mbhd)
  594.  
  595. char      ch;
  596. MBHEAD   *mbhd;
  597.  
  598.   {
  599.     if (!(mbhd->mbpc++ % 32))           /* neuer Datenbuffer faellig ?    */
  600.       mbhd->mbbp = ((MB *)(relink(allocb(),mbhd->mbl.tail)))->data; /* ja */
  601.     *mbhd->mbbp++ = ch;                 /* Zeichen in Buffer schreiben    */
  602.   }
  603.  
  604.  
  605. #else
  606.  
  607. #asm
  608.           public putchr?        ; globales Symbol
  609.  
  610. putchr?:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  611.           ld    L,(IX+6)        ; HL = mbhd
  612.           ld    H,(IX+7)
  613.           push  HL              ; (merken)
  614.           ld    DE,10           ; ->mbpc
  615.           add   HL,DE
  616.           ld    E,(HL)          ; DE = mbhd->mbpc++
  617.           inc   HL
  618.           ld    D,(HL)
  619.           inc   DE
  620.           ld    (HL),D
  621.           dec   HL
  622.           ld    (HL),E
  623.           dec   DE              ; (DE wieder korrigieren)
  624.           pop   HL              ; HL = mbhd
  625.           ld    A,E
  626.           and   31              ; DE % 32 = 0, d.h. neuer Buffer erforderlich ?
  627.           jr    NZ,?put1        ; nein -
  628.           push  HL              ; ja   -
  629.           push  HL
  630.           ld    DE,8            ;        (SP) = mbhd->mbbp
  631.           add   HL,DE
  632.           ex    (SP),HL
  633.           ld    DE,6            ;        DE = mbhd->mbl.tail
  634.           add   HL,DE
  635.           ld    E,(HL)
  636.           inc   HL
  637.           ld    D,(HL)
  638.           push  DE
  639.           call  allocb?         ;        HL = Freibuffer (Adresse)
  640.           push  HL
  641.           call  relink?         ;        relink(Freibuffer,mbhd->mbl.tail)
  642.           pop   DE
  643.           pop   DE
  644.           ld    DE,4            ;        HL = Freibuffer->data
  645.           add   HL,DE
  646.           ex    DE,HL           ;        DE = Freibuffer->data
  647.           pop   HL              ;        HL = mbhd->mbbp (s.o. (SP) = ... )
  648.           ld    (HL),E          ;        mbhd->mbbp = DE
  649.           inc   HL
  650.           ld    (HL),D
  651.           pop   HL              ;        HL = mbhd
  652.  
  653. ?put1:    ld    DE,8            ; *mbhd->mbbp++ = ch
  654.           add   HL,DE
  655.           ld    E,(HL)
  656.           inc   HL
  657.           ld    D,(HL)
  658.           inc   DE              ; (++mbhd->mbbp)
  659.           ld    (HL),D
  660.           dec   HL
  661.           ld    (HL),E
  662.           dec   DE
  663.           ld    A,(IX+4)        ; (A = ch)
  664.           ld    (DE),A
  665.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  666.           push  BC
  667.           pop   IX
  668.           ret                   ; das war's
  669. #endasm
  670.  
  671. #endif
  672.  
  673.  
  674.  
  675.  
  676.  
  677. /**************************************************************************\
  678. *                                                                          *
  679. * action      :  "get character"                                           *
  680. *                                                                          *
  681. *                Zeichen aus einem Messagebuffer holen. Datenbuffer-Poiner *
  682. *                setzen und Get-Count erhoehen. Uebergang in der           *
  683. *                Datenbufferliste vom Ende eines Datenbuffers zum          *
  684. *                naechsten ausfuehren.                                     *
  685. *                                                                          *
  686.  **************************************************************************
  687. *                                                                          *
  688. * parameter   :  mbhd    - Zeiger auf Kopf des Messagebuffers, aus dem     *
  689. *                          das Zeichen gelesen werden soll                 *
  690. *                                                                          *
  691. * r/o globals :  -                                                         *
  692. *                                                                          *
  693. * r/w globals :  -                                                         *
  694. *                                                                          *
  695. * locals      :  -                                                         *
  696. *                                                                          *
  697. * returns     :  aus dem Buffer gelesenes Zeichen                          *
  698. *                                                                          *
  699. \**************************************************************************/
  700.  
  701. #ifdef PORTABLE
  702.  
  703. getchr(mbhd)
  704.  
  705. MBHEAD *mbhd;
  706.  
  707.   {
  708.     if (!(mbhd->mbgc++ % 32))                            /* Ende Buffer ? */
  709.       mbhd->mbbp = ((MB *)(mbhd->mbbp)-1)->nextmb->data; /* ja, naechster */
  710.     return (*mbhd->mbbp++);                              /* Zeichen holen */
  711.   }
  712.  
  713. #else
  714.  
  715. #asm
  716.           public getchr?        ; globales Symbol
  717.  
  718. getchr?:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  719.           ld    L,(IX+4)        ; HL = mbhd
  720.           ld    H,(IX+5)
  721.           push  HL              ; (merken)
  722.           ld    DE,12           ; A = mbhd->mbgc++ % 32
  723.           add   HL,DE
  724.           ld    E,(HL)          ; (DE = mbhd->mbgc)
  725.           inc   HL
  726.           ld    D,(HL)
  727.           inc   DE              ; (++mbhd->mbgc)
  728.           ld    (HL),D
  729.           dec   HL
  730.           ld    (HL),E
  731.           dec   DE              ; (DE wieder korrigieren)
  732.           pop   HL              ; (HL = mbhd)
  733.           ld    A,E             ; A = (D)E % 32
  734.           and   31              ; noch Zeichen im aktuellen Datenbuffer ?
  735.           jr    NZ,?get1        ; ja   -
  736.           push  HL              ; nein - mbhd sichern
  737.           ld    DE,8            ;        DE = mbhd->mbbp
  738.           add   HL,DE
  739.           ld    E,(HL)
  740.           inc   HL
  741.           ld    D,(HL)
  742.           push  HL              ;        (&mbhd->mbbp + 1 sichern)
  743.           ld    HL,-36          ;        HL = mbhd->mbbp - 36 
  744.           add   HL,DE           ;           = Zeiger auf den Datenbufferkopf
  745.           ld    E,(HL)          ;        DE = Datenbufferkopf.next
  746.           inc   HL
  747.           ld    D,(HL)
  748.           ld    HL,4            ;             + 4
  749.           add   HL,DE           ;        = Zeiger auf Anfang naechste Daten
  750.           ex    DE,HL           ;        in DE
  751.           pop   HL              ;        HL = &mbhd->mbbp + 1
  752.           ld    (HL),D          ;        (HL-1) = DE, also mbhd->mbbp =
  753.           dec   HL              ;        Anfang des naechsten Datenbuffers
  754.           ld    (HL),E
  755.           pop   HL              ;        HL = mbhd
  756.           
  757. ?get1:    ld    DE,8            ; HL = *mbhd->mbbp++
  758.           add   HL,DE           ; (DE = mbhd->mbbp)
  759.           ld    E,(HL)
  760.           inc   HL
  761.           ld    D,(HL)
  762.           inc   DE              ; (++mbhd->mbbp)
  763.           ld    (HL),D
  764.           dec   HL
  765.           ld    (HL),E
  766.           dec   DE              ; (DE wieder korrigieren)
  767.           ld    A,(DE)          ; (A = *DE)
  768.           ld    L,A             ; (HL = A)
  769.           ld    H,0
  770.           or    A               ; (C-Konvention)
  771.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  772.           push  BC
  773.           pop   IX
  774.           ret                   ; das war's
  775. #endasm
  776.  
  777. #endif
  778.  
  779.  
  780.  
  781.  
  782.  
  783. /**************************************************************************\
  784. *                                                                          *
  785. * action      :  "rewind message buffer"                                   *
  786. *                                                                          *
  787. *                Message-Buffer (Kopf und Datenbufferliste) zuruecksetzen. *
  788. *                Get-Counter auf 0 setzen, Buffer-Pointer so setzen, dass  *
  789. *                beim naechsten getchr() auf das das erste Datenbyte des   *
  790. *                ersten Datenbuffers zugegriffen wird.                     *
  791. *                (Dies muss wie folgt geschehen, da der Get-Counter in     *
  792. *                jedem Fall auf 0 stehen muss und in getchr() auf % 32     *
  793. *                fuer das Positionieren auf den naechsten Datenbuffer      *
  794. *                abgetestet wird.)                                         *
  795. *                                                                          *
  796.  **************************************************************************
  797. *                                                                          *
  798. * parameter   :  mbhd    - Zeiger auf Kopf des Message-Buffers             *
  799. *                                                                          *
  800. * r/o globals :  -                                                         *
  801. *                                                                          *
  802. * r/w globals :  -                                                         *
  803. *                                                                          *
  804. * locals      :  -                                                         *
  805. *                                                                          *
  806. * returns     :  -                                                         *
  807. *                                                                          *
  808. \**************************************************************************/
  809.  
  810. #ifdef PORTABLE
  811.  
  812. VOID rwndmb(mbhd)
  813.  
  814. MBHEAD *mbhd;
  815.  
  816.   {
  817.     /* Kopf wie Datenbufferende */
  818.     mbhd->mbbp = (char *)(&((MBHEAD *)mbhd + 1)->mbl);
  819.     mbhd->mbgc = 0;                                    /* Bufferanfang    */
  820.   }
  821.  
  822. #else
  823.  
  824. #asm
  825.           public rwndmb?        ; globales Symbol
  826.  
  827. rwndmb?:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  828.           ld    E,(IX+4)        ; DE = mbhd
  829.           ld    D,(IX+5)
  830.           push  DE              ; (fuer spaeter merken)
  831.           ld    HL,40           ; HL = &((MB *)mbhd + 1)->mbl
  832.           add   HL,DE
  833.           ex    DE,HL           ; DE = HL, HL = mbhd
  834.           ld    BC,8            ; mbhd->mbgc = DE
  835.           add   HL,BC
  836.           ld    (HL),E
  837.           inc   HL
  838.           ld    (HL),D
  839.           pop   HL              ; HL = mbhd
  840.           ld    DE,12           ; mbhd->mbgc = 0
  841.           add   HL,DE
  842.           xor   A
  843.           ld    (HL),A
  844.           inc   HL
  845.           ld    (HL),A
  846.           pop   BC              ; alte Stackframezeiger wiedereinsetzen
  847.           push  BC
  848.           pop   IX
  849.           ret                   ; das war's
  850. #endasm
  851.  
  852. #endif
  853.  
  854.  
  855.  
  856.  
  857.  
  858. /**************************************************************************\
  859. *                                                                          *
  860. * action      :  "allocate buffer"                                         *
  861. *                                                                          *
  862. *                Leeren Buffer aus der Freiliste holen, Pogrammneustart    *
  863. *                wenn keine Buffer mehr in Freiliste.                      *
  864. *                                                                          *
  865.  **************************************************************************
  866. *                                                                          *
  867. * parameter   :  -                                                         *
  868. *                                                                          *
  869. * r/o globals :  -                                                         *
  870. *                                                                          *
  871. * r/w globals :  nmbfre  - Anzahl der Buffer in Freiliste freel            *
  872. *                freel   - verkettete Liste der freien Buffer              *
  873. *                                                                          *
  874. * locals      :  s.u.                                                      *
  875. *                                                                          *
  876. * returns     :  Zeiger auf freien Buffer, fall vorhanden                  *
  877. *                                                                          *
  878. \**************************************************************************/
  879.  
  880. #ifdef PORTABLE
  881.  
  882. LEHEAD *allocb()
  883.   {
  884.     LEHEAD *ret;                        /* Buffer Rueckgabewert           */
  885.  
  886.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  887.     if (!nmbfre--) reset();             /* Freibufferz., ggf. Neustart    */
  888.     ret = unlink(freel.head);           /* Buffer aus Liste aushaengen    */
  889.     decEI();                            /* Interrupts nun wieder erlaubt  */
  890.     return(ret);                        /* Zeiger auf Freibuffer zurueck  */
  891.   }
  892.  
  893. #else
  894.  
  895. #asm
  896.           public allocb?        ; globales Symbol
  897.  
  898. allocb?:  call  DIinc?          ; Interrupts verbieten (Listenkonsistenz)
  899.           ld    HL,(nmbfre?)    ; nmbfre--
  900.           dec   HL
  901.           ld    (nmbfre?),HL
  902.           inc   HL
  903.           ld    A,H             ; noch freie Buffer da ?
  904.           or    L
  905.           jr    NZ,?all1        ; ja   -
  906.           call  reset?          ; nein - Programmneustart (Crash)
  907. ?all1:    ld    HL,(freel?)     ; unlink(freel.head)
  908.           push  HL
  909.           call  unlink?
  910.           call  decEI?          ; Interrupts wieder erlauben
  911.           pop   HL              ; Zeiger auf Buffer zurueck
  912.           ld    A,H             ; (C-Konvention)
  913.           or    L
  914.           ret                   ; das war's
  915.  
  916. #endasm
  917.  
  918. #endif
  919.  
  920.  
  921.  
  922.  
  923.  
  924. /**************************************************************************\
  925. *                                                                          *
  926. * action      :  Element aus Liste aushaengen.                             *
  927. *                                                                          *
  928. *                                                                          *
  929. *                      le ---+                                             *
  930. *              vor           |     raus                hinter              *
  931. *            +--------+      +-->+--------+          +--------+            *
  932. *      ----->|        |--------->| prevle |--------->|        |----->      *
  933. *            +--------+          +--------+          +--------+            *
  934. *      <-----|        |<---------| nextle |<---------|        |<-----      *
  935. *            +--------+          +--------+          +--------+            *
  936. *            |        |          |        |          |        |            *
  937. *                                                                          *
  938. *                                                                          *
  939. *                                \/                                        *
  940. *                                                                          *
  941. *                                                                          *
  942. *             raus                    vor             hinter               *
  943. *           +--------+              +--------+      +--------+             *
  944. *    le --->| nextle |        ----->|        |----->|        |----->       *
  945. *           +--------+              +--------+      +--------+             *
  946. *           | prevle |        <-----|        |<-----|        |<-----       *
  947. *           +--------+              +--------+      +--------+             *
  948. *           |        |              |        |      |        |             *
  949. *                                                                          *
  950. *                                                                          *
  951.  **************************************************************************
  952. *                                                                          *
  953. * parameter   :  le      - Zeiger auf auszuhaengendes Listenelement        *
  954. *                                                                          *
  955. * r/o globals :  -                                                         *
  956. *                                                                          *
  957. * r/w globals :  -                                                         *
  958. *                                                                          *
  959. * locals      :  -                                                         *
  960. *                                                                          *
  961. * returns     :  le                                                        *
  962. *                                                                          *
  963. \**************************************************************************/
  964.  
  965. #ifdef PORTABLE
  966.  
  967. LEHEAD *unlink(le)
  968.  
  969. LEHEAD *le;
  970.  
  971.   {
  972.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  973.     le->prevle->nextle = le->nextle;    /* Hinliste ohne le               */
  974.     le->nextle->prevle = le->prevle;    /* Rueckliste ohne le             */
  975.     decEI();                            /* Interrupts wieder erlaubt      */
  976.     return(le);                         /* Zeiger auf das Element zurueck */
  977.   }
  978.  
  979. #else
  980.  
  981. #asm
  982.           public unlink?        ; globales Symbol
  983.  
  984. unlink?:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  985.           call  DIinc?          ; Interrupts verbieten (Listenkonsistenz !)
  986.           ld    L,(IX+4)        ;   HL -> | raus |
  987.           ld    H,(IX+5)
  988.           push  HL              ;   le fuer return() merken
  989.           ld    C,(HL)          ;   BC -> | hinter |
  990.           inc   HL
  991.           ld    B,(HL)
  992.           inc   HL              ;   DE -> | vor |
  993.           ld    E,(HL)
  994.           inc   HL
  995.           ld    D,(HL)
  996.           dec   HL              ;   ( wieder HL -> | raus | ) 
  997.           dec   HL
  998.           dec   HL
  999.           ex    DE,HL           ;   HL -> | vor |, DE -> | hinter|
  1000.           ld    (HL),C          ; * vor.nextle -> | hinter |
  1001.           inc   HL
  1002.           ld    (HL),B
  1003.           dec   HL
  1004.           inc   BC              ;   BC -> | hinter.prevle |
  1005.           inc   BC
  1006.           ld    A,L             ; * hinter.prevle -> | vor |
  1007.           ld    (BC),A 
  1008.           inc   BC
  1009.           ld    A,H
  1010.           ld    (BC),A
  1011.           call  decEI?          ;   Interrupts wieder erlauben
  1012.           pop   HL              ;   le holen ...
  1013.           ld    A,H             ;   ... und zurueckgeben
  1014.           or    L
  1015.           pop   BC              ;   alte Stackframezeiger wiedereinsetzen
  1016.           push  BC
  1017.           pop   IX
  1018.           ret                   ;   das war's
  1019. #endasm
  1020.  
  1021. #endif
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027. /**************************************************************************\
  1028. *                                                                          *
  1029. * action      :  Element in Liste einhaengen.                              *
  1030. *                                                                          *
  1031. *                                                                          *
  1032. *             neu                     vor             hinter               *
  1033. *           +--------+              +--------+      +--------+             *
  1034. *   new --->| nextle |     pred --->|        |----->|        |----->       *
  1035. *           +--------+              +--------+      +--------+             *
  1036. *           | prevle |        <-----|        |<-----|        |<-----       *
  1037. *           +--------+              +--------+      +--------+             *
  1038. *           |        |              |        |      |        |             *
  1039. *                                                                          *
  1040. *                                                                          *
  1041. *                                \/                                        *
  1042. *                                                                          *
  1043. *                                                                          *
  1044. *                     new ---+                                             *
  1045. *              vor           |     neu                 hinter              *
  1046. *            +--------+      +-->+--------+          +--------+            *
  1047. *   pred --->|        |--------->| prevle |--------->|        |----->      *
  1048. *            +--------+          +--------+          +--------+            *
  1049. *      <-----|        |<---------| nextle |<---------|        |<-----      *
  1050. *            +--------+          +--------+          +--------+            *
  1051. *            |        |          |        |          |        |            *
  1052. *                                                                          *
  1053. *                                                                          *
  1054.  **************************************************************************
  1055. *                                                                          *
  1056. * parameter   :  new     - Zeiger auf einzuhaengendes Listenelement        *
  1057. *                pred    - Zeiger auf Listenelement, hinter dem new        *
  1058. *                          eingehaengt werden soll                         *
  1059. *                                                                          *
  1060. * r/o globals :  -                                                         *
  1061. *                                                                          *
  1062. * r/w globals :  -                                                         *
  1063. *                                                                          *
  1064. * locals      :  -                                                         *
  1065. *                                                                          *
  1066. * returns     :  new                                                       *
  1067. *                                                                          *
  1068. \**************************************************************************/
  1069.  
  1070. #ifdef PORTABLE
  1071.  
  1072. LEHEAD *relink(new,pred)
  1073.  
  1074. LEHEAD *new;
  1075. LEHEAD *pred;
  1076.  
  1077.   {
  1078.     DIinc();                            /* keine Ints. > Listenkonsistenz */
  1079.     new->nextle = pred->nextle;         /* Vorzeiger im neuen Element     */
  1080.     new->prevle = pred;                 /* Rueckzeiger im neuen Element   */
  1081.     new->nextle->prevle = new;          /* Rueckzeiger dahinter           */
  1082.     pred->nextle = new;                 /* Vorzeiger davor                */
  1083.     decEI();                            /* Interrupts wieder erlaubt      */
  1084.     return(new);                        /* Zeiger auf neues Element       */
  1085.   }
  1086.  
  1087. #else
  1088.  
  1089. #asm
  1090.           public relink?        ; globales Symbol
  1091.  
  1092. relink?:  call  ?en             ; IX/BC Stackframezeiger (Funktionsparameter)
  1093.           call  DIinc?          ; Interrupts verbieten (Listenkonsistenz !)
  1094.           ld    L,(IX+6)        ;   HL -> | vor |
  1095.           ld    H,(IX+7)
  1096.           ld    E,(IX+4)        ;   DE -> | neu |
  1097.           ld    D,(IX+5)
  1098.           push  DE              ;   new fuer return() merken
  1099.           ld    C,(HL)          ;   BC -> | hinter |     
  1100.           inc   HL
  1101.           ld    B,(HL)
  1102.           ld    (HL),D          ; * vor.nextle -> | neu |
  1103.           dec   HL
  1104.           ld    (HL),E
  1105.           ex    DE,HL           ;   HL -> | neu |, DE -> | vor |
  1106.           ld    (HL),C          ; * neu.nextle -> | hinter |
  1107.           inc   HL
  1108.           ld    (HL),B
  1109.           dec   HL
  1110.           inc   BC              ;   BC -> | hinter.prevle |
  1111.           inc   BC
  1112.           ld    A,L             ; * hinter.prevle -> | neu | 
  1113.           ld    (BC),A
  1114.           inc   BC
  1115.           ld    A,H
  1116.           ld    (BC),A
  1117.           inc   HL              ;   HL -> | neu.prevle |
  1118.           inc   HL
  1119.           ld    (HL),E          ; * neu.prevle -> | vor |
  1120.           inc   HL
  1121.           ld    (HL),D
  1122.           call  decEI?          ;   Interrupts wieder erlauben
  1123.           pop   HL              ;   new holen ...
  1124.           ld    A,H             ;   ... und zurueckgeben
  1125.           or    L
  1126.           pop   BC              ;   alte Stackframezeiger wiedereinsetzen
  1127.           push  BC
  1128.           pop   IX
  1129.           ret                   ;   das war's
  1130. #endasm
  1131.  
  1132. #endif
  1133.  
  1134.  
  1135.  
  1136. /* Ende von L2D.C */
  1137.