home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 540.TNL1.MAC < prev    next >
Text File  |  1988-05-12  |  96KB  |  2,019 lines

  1. ; ***********************************************************************
  2. ; *                                                                     *
  3. ; *                                                                     *
  4. ; *    *****                      *****                                 *
  5. ; *      *****                  *****                                   *
  6. ; *        *****              *****                                     *
  7. ; *          *****          *****                                       *
  8. ; *  ***************      ***************                               *
  9. ; *  *****************  *****************                               *
  10. ; *  ***************      ***************                               *
  11. ; *          *****          *****          The Net.                     *
  12. ; *        *****              *****        Portable. Compatible.        *
  13. ; *      *****                  *****      Public Domain.               *
  14. ; *    *****                      *****    By NORD><LINK.               *
  15. ; *                                                                     *
  16. ; *                                                                     *
  17. ; *                                                                     *
  18. ; *    TNL1.MAC   -   Z80 Level 1, Hardwareanpassungen, Interrupts      *
  19. ; *                                                                     *
  20. ; *    angelegt:      DC4OX                                             *
  21. ; *    modifiziert:                                                     *
  22. ; *                                                                     *
  23. ; ***********************************************************************
  24.  
  25.  
  26.  
  27. ;
  28. ; Achtung :  Hier wird mit "Crosslink" ausschliesslich die Verbindung
  29. ;            zweier TNC's ueber die RS232-Schnittstelle bezeichnet.
  30. ;            Somit wird der RS232-Kanal zwischen 2 TNC's als
  31. ;            "Crosslink-Kanal" bezeichnet, der Modem-Kanal als
  32. ;            "HDLC-Kanal".
  33. ;
  34.  
  35.  
  36.  
  37.  
  38.  
  39. ; =======================================================================
  40. ;                                                                        
  41. ;   Equates                                                   
  42. ;                                                                        
  43. ; =======================================================================
  44.  
  45.  
  46.  
  47. ;
  48. ; benutzte "Magic Number" zum RAM-Test Warmstart/Kaltstart
  49. ;
  50. MAGIC     equ   4D5Ah
  51.  
  52.  
  53.  
  54. ;
  55. ; Hardware-I/O-Ports
  56. ;
  57. SIADAT    equ   0               ; SIO Kanal A (HDLC)  Data
  58. SIACTL    equ   1               ; SIO Kanal A (HDLC)  Control
  59. SIBDAT    equ   2               ; SIO Kanal B (RS232) Data
  60. SIBCTL    equ   3               ; SIO Kanal B (RS232) Control
  61.  
  62.  
  63.  
  64. ;
  65. ; niedrigste RAM-Speicherstelle
  66. ;
  67. RAMBOT    equ   8000h
  68.  
  69.  
  70.  
  71. ;
  72. ; ASCII-Kontrollzeichen
  73. ;
  74. ASTX      equ   02h             ; ASCII Start of Text      = Control B
  75. AETX      equ   03h             ; ASCII End of Text        = Control C
  76. ADLE      equ   10h             ; ASCII Data Link Escape   = Control P
  77. ACAN      equ   18h             ; ASCII Cancel             = Control X
  78. AESC      equ   1Bh             ; ASCII Escape
  79.  
  80.  
  81.  
  82. ;
  83. ; Hostterminal FIFO-Groessen
  84. ;
  85. HORXFL    equ   256             ; RX FIFO Laenge
  86. HOTXFL    equ   256             ; TX FIFO Laenge
  87.  
  88.  
  89.  
  90.  
  91.  
  92. ; =======================================================================
  93. ;                                                                        
  94. ;   Arbeitsspeicher                                                      
  95. ;                                                                        
  96. ; =======================================================================
  97.  
  98.           dseg
  99.  
  100.  
  101.  
  102. RAMVEC:   ds    16      ; Interrupt Vektor im RAM
  103.  
  104. ;
  105. ; Hostkanal, SIO Kanal B, RS232-Schnittstelle,
  106. ; wenn Hostterminal angeschlossen
  107. ;
  108. HORXCC:   ds    2       ; RX "character count"   Anzahl Zeichen 
  109. HORXFI:   ds    HORXFL  ; RX "fifo"              FIFO-Ringspeicher
  110. HORXIP:   ds    2       ; RX "input pointer"     Eingangszeiger
  111. HORXOP:   ds    2       ; RX "output pointer"    Ausgangszeiger
  112. HOTXCC:   ds    2       ; TX "character count"   Anzahl Zeichen
  113. HOTXFI:   ds    HOTXFL  ; TX "fifo"              FIFO-Ringspeicher
  114. HOTXIP:   ds    2       ; TX "input pointer"     Eingangszeiger
  115. HOTXOP:   ds    2       ; TX "output pointer"    Ausgangszeiger
  116.  
  117. ;
  118. ; SIO Kanal B, RS232-Schnittstelle
  119. ;
  120. SIBWR5:   ds    1       ; Sicherung WR5, Tx-Modus
  121. SIBRR0:   ds    1       ; Sicherung RR0, Status
  122.  
  123. ;
  124. ; Crosslink, SIO Kanal B, RS232-Schnittstelle,
  125. ; wenn TNC im Crosslink betrieben
  126. ;
  127. CRXSTA:   ds    1       ; RX "state"
  128.                         ;    0 - RX inaktiv
  129.                         ;    1 - RX aktiv, innerhalb Frame
  130.                         ;    2 - RX aktiv, letztes Zeichen war DLE, naechstes
  131.                         ;        wird nicht interpretiert (STX/ETX/DLE)
  132.                         ;    3 - Frameende, naechstes Zeichen ist Checksum
  133. CRXFCS:   ds    1       ; RX "frame checksum" (8 Bit, Summe modulo 256)
  134. CTXSTA:   ds    1       ; TX "state"
  135.                         ;    0 - TX inaktiv
  136.                         ;    1 - nachdem Port frei wird (DTR high)
  137.                         ;        (ASync-)WAIT-Sendesequenz eineiten
  138.                         ;    2 - nachdem Port frei wird (DTR high)
  139.                         ;        Nicht-(Async-)WAIT-Sendesequenz einleiten
  140.                         ;    3 - (Async-)WAIT abwarten
  141.                         ;    4 - Vorlauftraeger (CTS low) gesetzt, 
  142.                         ;        2,5 msec warten
  143.                         ;    5 - TX aktiv, innerhalb Frame
  144.                         ;        (vor ETX/Checksumme)
  145.                         ;    6 - TX aktiv, Frameende, ETX gesendet,
  146.                         ;        weitere Frames vorhanden
  147.                         ;    7 - TX aktiv, Frameende, ETX gesendet,
  148.                         ;        keine weiteren Frames vorhanden
  149.                         ;    8 - TX aktiv, Frameende, Checksumme gesendet,
  150.                         ;        weitere Frames vorhanden
  151.                         ;    9 - TX aktiv, Frameende, Checksumme gesendet,
  152.                         ;        keine weiteren Frames vorhanden
  153.                         ;   10 - wie 9, vorletztes Zeichen aus internem
  154.                         ;        SIO-FIFO gesendet
  155.                         ;   11 - wie 9, letztes Zeichen aus internem 
  156.                         ;        SIO-FIFO gesendet
  157. CTXFCS:   ds    1       ; TX "frame checksum" (8 Bit, Summe modulo 256)
  158. CTXCSA:   ds    1       ; TX "character save" fuer Zeichen mit DLE-Vorlauf
  159.  
  160.  
  161. ;
  162. ; HDLC-Kanal, SIO Kanal A, PR-Modemschnittstelle
  163. ;
  164. SIAWR5:   ds    1       ; Sicherung WR5, Tx-Modus
  165. SIARR0:   ds    1       ; Sicherung RR0, Status
  166. HRXSTA:   ds    1       ; RX "state"
  167.                         ;    0 - RX ausserhalb Frame
  168.                         ;    1 - RX innerhalb Frame
  169. HRXLCH:   ds    1       ; RX "last character" 1-Zeichen-FIFO, Zeichen erst
  170.                         ;   gueltig, wenn Nicht-Frameende-Status von SIO
  171. HTXSTA:   ds    1       ; TX "state"
  172.                         ;    0 - TX inaktiv
  173.                         ;    1 - nachdem Port frei wird (DCD low)
  174.                         ;        WAIT-Sendesequenz einleiten
  175.                         ;    2 - nachdem Port frei wird (DCD low)
  176.                         ;        Nicht-WAIT-Sendesequenz einleiten
  177.                         ;    3 - WAIT warten
  178.                         ;    4 - TX aktiv, PTT, TXDELAY abwarten
  179.                         ;    5 - TX aktiv, innerhalb Frame Datenbytes
  180.                         ;    6 - TX aktiv, letztes Datenbyte fuer Frame
  181.                         ;        gesendet, weitere Frames vorhanden
  182.                         ;    7 - TX aktiv, letztes Datenbyte fuer Frame
  183.                         ;        gesendet, keine weiteren Frames vorhanden
  184.                         ;        (mit 6 oder 7 laeuft TX in den TX-Underrun/
  185.                         ;        EoM-Interrupt, naechster TX-Buffer-Empty-
  186.                         ;        Interrupt :  1. CRC-Byte hat SIO verlassen) 
  187.                         ;    8 - TX aktiv, CRC verlaesst SIO
  188.                         ;    9 - TX aktiv, Frameendeflag verlaesst SIO
  189.                         ;   10 - TX aktiv, Frameendeflag hat SIO komplett
  190.                         ;        verlassen
  191.  
  192. ;
  193. ; Zaehler
  194. ;
  195. TICDIV:   ds    1       ; Zaehler bis 12, 1200Hz Interrupts -> 10msec
  196. HTXWAI:   ds    1       ; 10msec HDLC-TX-Wartezaehler (WAIT/TXDELAY) 
  197. CTXWAI:   ds    1       ; 1200Hz Crosslink-TX-Wartezaehler (Async-WAIT)
  198.  
  199. ;
  200. ; Sonstiges
  201. ;
  202. DEICNT:   ds    1       ; Interrupt Verbietungsstufe
  203. RAMTOP:   ds    2       ; oberste verfuegbare RAM-Speicherstelle
  204. URAND:    ds    2       ; (fuer random(), damit Gleichverteilung)
  205.  
  206.  
  207.  
  208.  
  209.  
  210. ; =======================================================================
  211. ;                                                                        
  212. ;   Code                                                                 
  213. ;                                                                        
  214. ; =======================================================================
  215.  
  216.           cseg
  217.  
  218.  
  219.  
  220. ; +---------------------------------------------------------------------+
  221. ; |                                                                     |
  222. ; | Reset-Einsprungsvektor, RST-Vektoren.                               |
  223. ; |                                                                     |
  224. ; +---------------------------------------------------------------------+
  225.  
  226.  
  227.           public reset?
  228.  
  229.           extrn ?inc                    ; aus CRUNTIME
  230.           extrn ?sxt
  231.           extrn ?gf
  232.           extrn ?g
  233.           extrn ?sn
  234.           extrn ?addhl
  235.           extrn ?loc
  236.  
  237.  
  238. reset?:   jp    L1INIT                  ; Resetvektor
  239.           db    0,0,0,0,0
  240.           jp    ?inc                    ; RST08 (HL):=(HL)+1, 16 Bit
  241.           db    0,0,0,0,0
  242.           jp    ?sxt                    ; RST10 HL:=A sign extension
  243.           db    0,0,0,0,0
  244.           jp    ?gf                     ; RST18 HL:=(BC)
  245.           db    0,0,0,0,0
  246.           jp    ?g                      ; RST20 HL:=(HL)
  247.           db    0,0,0,0,0
  248.           jp    ?sn                     ; RST28 HL:=!HL
  249.           db    0,0,0,0,0
  250.           jp    ?addhl                  ; RST30 Offset auf HL addieren
  251.           db    0,0,0,0,0
  252.           jp    ?loc                    ; RST38 Locals laden/loeschen
  253.  
  254.  
  255.  
  256.  
  257.  
  258. ; +---------------------------------------------------------------------+
  259. ; |                                                                     |
  260. ; | Default-Parameter.                                                  |
  261. ; |                                                                     |
  262. ; +---------------------------------------------------------------------+
  263.  
  264.           public   defCAL?, defIDE?, defDES?, defWQU?, defCH0?, defCH1?
  265.           public   defOBC?, defOBB?, defBRI?, defTLI?, defTTO?, defTTR?
  266.           public   defTAC?, defTBS?, defTWI?, defCON?, defNOA?, defPER?
  267.           public   defSLO?, defRAK?, defMAF?, defL2T?, defLT2?, defLT3?
  268.           public   defRPA?, defVAL?, defBEA?, defCQ?,  defDPA?, defXFP?
  269.           public   defESC?, defTp?,  defPWD?, defINF?
  270.  
  271. defCAL?:  db      'NO1DE ', 60h         ; Call des TNC
  272. defIDE?:  db      'THENET'              ; Ident des TNC
  273. defDES?:  dw      50                    ; Laenge der Destination Liste
  274. defWQU?:  dw      1                     ; minimale Qualitaet fuer Autoupdate
  275. defCH0?:  dw      100                   ; HDLC Kanal Qualitaet
  276. defCH1?:  dw      255                   ; RS232 Kanal Qualitaet
  277. defOBC?:  dw      6                     ; Anfangswert Knotenlebensdauer
  278. defOBB?:  dw      5                     ; Restlebensdauer fuer Rundspruch
  279. defBRI?:  dw      1800                  ; Rundspruchintervall
  280. defTLI?:  dw      10                    ; Anfangswert Paketlebensdauer
  281. defTTO?:  dw      300                   ; Timeout in Level3
  282. defTTR?:  dw      2                     ; Versuche in Level3
  283. defTAC?:  dw      6                     ; Level3 Wartezeit bis ACK
  284. defTBS?:  dw      180                   ; Level3 Busy Wartezeit
  285. defTWI?:  dw      4                     ; Fenstergroesse in Level3
  286. defCON?:  dw      4                     ; gebufferte Frames je Verbindung
  287. defNOA?:  dw      900                   ; no-activity-timeout
  288. defPER?:  dw      64                    ; Entschlossenheit fuer Sendung frei
  289. defSLO?:  dw      10                    ; Zeitschlitzbreite
  290. defRAK?:  dw      5                     ; Level2, Timer1
  291. defMAF?:  dw      2                     ; Level2, Fenstergroesse
  292. defL2T?:  dw      10                    ; Level2, Versuche
  293. defLT2?:  dw      100                   ; Level2, Timer2
  294. defLT3?:  dw      18000                 ; Level2, Timer3
  295. defRPA?:  dw      0                     ; Level2 Digipeating Freigabe
  296. defVAL?:  dw      1                     ; Calls pruefen
  297. defBEA?:  dw      2                     ; Bakenmodus
  298. defCQ?:   dw      1                     ; CQ-Ruf erlaubt j/n
  299. defDPA?:  db      0                     ; Full-Duplex j/n
  300. defXFP?:  db      0                     ; Flags in den Pausen
  301. defESC?:  db      01Bh                  ; Befehlseinleitungszeichen (Host)
  302. defTp?:   db      30                    ; Senderverzoegerung
  303.  
  304. defPWD?:  db      'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789   '
  305.           db      'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789   ',0   ; Passwort
  306.  
  307. defINF?:  db      'SOFTWARE VON NORD><LINK  -  SOFTWARE VON'
  308.           db      ' NORD><LINK  -  SOFTWARE VON NORD><LINK ',0   ; Infotext
  309.  
  310.  
  311.  
  312.  
  313.  
  314. ; +---------------------------------------------------------------------+
  315. ; |                                                                     |
  316. ; | SIO (HDLC, RS232) Initialisierungstabellen.                         |
  317. ; |                                                                     |
  318. ; +---------------------------------------------------------------------+
  319.  
  320. ;
  321. ; Mit "Pin" ist immer der SIO-Pin gemeint.
  322. ; Mit "Modemstecker" ist der RS232-Stecker gemeint - "Modem" in diesem
  323. ; Zusammenhang bezieht sich auf die Signalbezeichung, der TNC wird ja
  324. ; bei Anschluss an einen Rechner oder an ein Terminal als "Modem"
  325. ; betrieben.
  326. ;
  327.  
  328.  
  329.  
  330. ;
  331. ; SIO Kanal B, RS232 (Hostterminal oder Crosslink)
  332. ;
  333. SIBINI:   db    018h            ; WR 0 :  Channel Reset
  334.           db    2               ; WR 2 :
  335.           db    000h            ;   Interrupt Vector (Page-Anfang)
  336.           db    4               ; WR 4 :
  337.           db    044h            ;   /16 Clock, 1 Stopbit, kein Parity
  338.           db    5               ; WR 5 :
  339. SIBIW5:   db    0EAh            ;   Tx 8 Bit, Tx Enable, Pin /DTR low,
  340.                                 ;   Pin /RTS low -> Modemstecker CTS high
  341.           db    3               ; WR 3 :
  342.           db    0C1h            ;   Rx 8 Bit, Rx Enable
  343.           db    1               ; WR 1 :
  344.           db    01Fh            ;   Interrupt on all Rx Character, Status
  345.                                 ;   affects Vector, Tx Interrupt Enable,
  346.                                 ;   External/Status Interrupt Enable
  347.           db    010h            ; WR 0 :  Reset External/Status Interrupts
  348. SIBIEN:
  349.  
  350.  
  351.  
  352. ;
  353. ; SIO Kanal A, HDLC (Packet-Radio-Modem)
  354. ;
  355. SIAINI:   db      018h          ; WR 0 :  Channel Reset
  356.           db      4             ; WR 4 :
  357.           db      020h          ;   /1 Clock, SDLC Mode (01111110 Flag),
  358.                                 ;   Sync Modes Enable
  359.           db      5             ; WR 5 :
  360. SIAIW5:   db      0E1h          ;   Tx 8 Bit, CCITT CRC, Tx CRC Enable,
  361.                                 ;   Pin /DTR low, Pin /RTS high -> PTT aus 
  362.           db      3             ; WR 3 :
  363. SIAIW3:   db      0D9h          ;   Rx 8 Bit, Hunt Phase, Rx CRC Enable,
  364.                                 ;   Rx Enable
  365.           db      7             ; WR 7 :
  366.           db      07Eh          ;   01111110 Flag
  367.           db      1             ; WR 1 :
  368.           db      01Bh          ;   Interrupt on all Rx Character,
  369.                                 ;   Tx Interrupt Enable,
  370.                                 ;   External/Status Interrupt Enable
  371.           db      010h          ; WR 0 :  Reset External/Status Interrupts
  372. SIAIEN:
  373.  
  374.  
  375.  
  376.  
  377.  
  378. ; +---------------------------------------------------------------------+
  379. ; |                                                                     |
  380. ; | Interrupt-Vektor-Tabelle (wird ins RAM uebertragen).                |
  381. ; |                                                                     |
  382. ; +---------------------------------------------------------------------+
  383.  
  384. ROMVEC:   dw    SIBTBE          ; SIO B (RS232) Tx Buffer Empty
  385.           dw    SIBESC          ; SIO B (RS232) External/Status Change
  386.           dw    SIBRCA          ; SIO B (RS232) Rx Character Available
  387.           dw    SIBSRC          ; SIO B (RS232) Special Receive Condition
  388.           dw    SIATBE          ; SIO A (HDLC)  Tx Buffer Empty
  389.           dw    SIAESC          ; SIO A (HDLC)  External/Status Change
  390.           dw    SIARCA          ; SIO A (HDLC)  Rx Character Available
  391.           dw    SIASRC          ; SIO A (HDLC)  Special Receive Condition
  392. ROMVEN:
  393.  
  394.  
  395.  
  396.  
  397.  
  398. ; +---------------------------------------------------------------------+
  399. ; |                                                                     |
  400. ; | Level 1 Initialisierung nach einem Reset.                           |
  401. ; |                                                                     |
  402. ; |   - Kaltstart :  Speicherausbau feststellen                         |
  403. ; |   - Stack setzen                                                    |
  404. ; |   - SIO initialisieren                                              |
  405. ; |   - Level 1 Variable setzen                                         |
  406. ; |   - Interrupts initialisieren                                       |
  407. ; |   - Interrupts erlauben                                             |
  408. ; |   - Sprung ins Hauptprogramm                                        |
  409. ; |                                                                     |
  410. ; +---------------------------------------------------------------------+
  411.  
  412.           external mainf?       ; C Hauptprogramm
  413.           external magicn?      ; im Hauptprogramm definierte Variable
  414.           external stack?       ; Stack im Hauptprogramm definiert
  415.  
  416. L1INIT:   di                    ; Interrupts verbieten fuer Initialisierung
  417.  
  418.           ld    HL,(magicn?)    ; RAM ok = Warmstart, d.h.
  419.           ld    DE,MAGIC        ; Magic Number noch        
  420.           or    A               ; unveraendert,
  421.           sbc   HL,DE           ; wie ins RAM geschrieben ?
  422.           jr    Z,L1INI2        ; ja   - RAM-Bestueckung nicht testen
  423.  
  424.           ld    HL,RAMBOT+3FFFh ; nein - Ende RAM bei 16kB
  425.           ld    DE,RAMBOT+7FFFh ; Ende RAM bei 32kB
  426.           xor   A               ; 0 
  427.           ld    (HL),A          ; in beide moegliche
  428.           ld    (DE),A          ; RAM-Enden
  429.           dec   (HL)            ; oberes RAM-Ende = 0FFh
  430.           ld    A,(DE)          ; hat sich unteres RAM-Ende geaendert ?
  431.           or    A               ; (16kB-Bestueckung -> Spiegelung)
  432.           jr    NZ,L1INI1       ; ja   - es sind nur 16kB
  433.           inc   A               ; A = 1
  434.           ld    (DE),A          ; an unteres RAM-Ende
  435.           inc   (HL)            ; 0 an oberes RAM-Ende, auch gespiegelt ?
  436.           jr    NZ,L1INI1       ; ja   - andere Hardware, aber auch nur 16kB
  437.           ex    DE,HL           ; nein - 32kB RAM
  438. L1INI1:   ld    (RAMTOP),HL     ; oberste RAM-Speicherstelle merken
  439.  
  440. L1INI2:   ld    SP,stack?+1     ; Stack setzen
  441.  
  442.           im    2               ; Interruptmode 2 = Vektorinterrupts
  443.           ld    A,RAMBOT>>8     ; Interrupt Vektor Page = RAM Anfang
  444.           ld    I,A
  445.           ld    HL,ROMVEC          ; Interrupt-Vektor vom ROM
  446.           ld    DE,RAMVEC          ; ins RAM
  447.           ld    BC,ROMVEN-ROMVEC   ; laden
  448.           ldir
  449.  
  450.           ld    HL,SIBINI       ; SIO B (RS232) initialisieren
  451.           ld    BC,SIBCTL|((SIBIEN-SIBINI)<<8)
  452.           otir
  453.           in    A,(SIBCTL)      ; SIO B initialen Status holen
  454.           ld    (SIBRR0),A      ; und merken
  455.           ld    A,(SIBIW5)      ; SIO B initialen Tx-Modus holen
  456.           ld    (SIBWR5),A      ; und merken
  457.  
  458.           ld    HL,SIAINI       ; SIO A (HDLC) initialisieren
  459.           ld    BC,SIACTL|((SIAIEN-SIAINI)<<8)
  460.           otir
  461.           in    A,(SIACTL)      ; SIO A initialen Status holen
  462.           ld    (SIARR0),A      ; und merken
  463.           ld    A,(SIAIW5)      ; SIO A initialen Tx-Modus holen
  464.           ld    (SIAWR5),A      ; und merken
  465.  
  466.           call  HOINIT          ; Host-FiFo's initialisieren  
  467.           xor   A               ; A = 0
  468.           ld    (CRXSTA),A      ; Crosslink RX inaktiv
  469.           ld    (CTXSTA),A      ; Crosslink TX inaktiv
  470.           ld    (HRXSTA),A      ; HDLC RX ausserhalb Frame
  471.           ld    (HTXSTA),A      ; HDLC TX inaktiv
  472.           ld    (TICDIV),A      ; 1200Hz Zaehler starten
  473.           ld    (HTXWAI),A      ; HDLC Wartetimer inaktiv
  474.           ld    (CTXWAI),A      ; Crosslink Wartetimer inaktiv 
  475.           ld    (DEICNT),A      ; keine Interrupt-Verbietungsstufe
  476.  
  477.           jp    mainf?          ; ab ins Hauptprogramm
  478.  
  479.  
  480.  
  481.  
  482.  
  483. ; +---------------------------------------------------------------------+
  484. ; |                                                                     |
  485. ; | C :  BOOLEAN ishget()   "is host get"                               |
  486. ; |                                                                     |
  487. ; | TRUE   -  (HL=1, Z=0) Hostterminal an RS232 angeschlossen und       |
  488. ; |           Zeichen vom Terminal vorhanden (in RX-FIFO)               |
  489. ; |                                                                     |
  490. ; | FALSE  -  (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen     |
  491. ; |           oder kein Zeichen von Terminal vorhanden (in RX-FIFO)     |
  492. ; |                                                                     |
  493. ; | A benutzt, HL Returnwert.                                           |
  494. ; |                                                                     |
  495. ; +---------------------------------------------------------------------+
  496.  
  497.           public ishget?
  498.  
  499. ishget?:  call  ishost?         ; Hostterminal an RS232 ?
  500.           ret   Z               ; nein - dann nie frei (FALSE zurueck)
  501.           ld    HL,(HORXCC)     ; Zeichenzaehler Host-FIFO RX = 0 ?
  502.           ld    A,H
  503.           or    L
  504.           ret   Z               ; ja   - FALSE zurueck
  505.           ld    HL,1            ; nein - TRUE zurueck
  506.           ret
  507.  
  508.  
  509.  
  510.  
  511.  
  512. ; +---------------------------------------------------------------------+
  513. ; |                                                                     |
  514. ; | C :  hgetc()   "host get character"                                 |
  515. ; |                                                                     |
  516. ; | Zeichen von Hostterminal holen, falls angeschlossen und Zeichen da. |
  517. ; | Falls kein Hostterminal angeschlossen, ASCII Cancel zurueckgeben.   |
  518. ; | Falls kein Zeichen da, warten auf Zeichen.                          |
  519. ; |                                                                     |
  520. ; | A, DE benutzt, HL Returnwert.                                       |
  521. ; |                                                                     |
  522. ; +---------------------------------------------------------------------+
  523.  
  524.           public hgetc?
  525.  
  526. hgetc?:   call  ishost?         ; Hostterminal an RS232 ?
  527.           ld    A,ACAN          ; nein - ASCII CAN = "bisherige Eingabe
  528.           jr    Z,hgetc2        ;        Loeschen" zurueck
  529.           call  ishget?         ; ja   - Zeichen vom Hostterminal da ?
  530.           jr    Z,hgetc?        ; nein - auf Zeichen warten
  531.           di                    ; ja   - keine Ints (kein Zeigerzugriff)
  532.           ld    HL,(HORXCC)     ; RX-FIFO Zeichenzaehler - 1
  533.           dec   HL
  534.           ld    (HORXCC),HL
  535.           ld    HL,(HORXOP)     ; Output-Zeiger
  536.           ld    A,(HL)          ; Zeichen aus FIFO holen
  537.           inc   HL              ; Zeiger auf naechstes Zeichen
  538.           ex    DE,HL
  539.           ld    HL,HORXFI+HORXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  540.           or    A                       ; "FIFO Wrap Around" ?
  541.           sbc   HL,DE
  542.           jr    NC,hgetc1       ; nein -
  543.           ld    DE,HORXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  544. hgetc1:   ld    (HORXOP),DE     ; Zeiger abspeichern
  545.           ei                    ; Interrupt wieder frei
  546. hgetc2:   ld    L,A             ; Zeichen C-like zurueck = return(chr)
  547.           ld    H,0
  548.           or    A
  549.           ret                   ; das war's
  550.  
  551.  
  552.  
  553.  
  554.  
  555. ; +---------------------------------------------------------------------+
  556. ; |                                                                     |
  557. ; | C :  BOOLEAN ishput()   "is host put"                               |
  558. ; |                                                                     |
  559. ; | TRUE   -  (HL=1, Z=0) Hostterminal an RS232 angeschlossen und es    |
  560. ; |           koennen Zeichen gesendet werden an Hostterminal           |
  561. ; |           (TX-FIFO leer)                                            |
  562. ; |                                                                     |
  563. ; | FALSE  -  (HL=0, Z=1) Hostterminal nicht an RS232 angeschlossen     |
  564. ; |           oder es duerfen keine Zeichen gesendet werden an          |
  565. ; |           Hostterminal (TX-FIFO nicht leer)                         |
  566. ; |                                                                     |
  567. ; | A benutzt, HL Returnwert.                                           |
  568. ; |                                                                     |
  569. ; +---------------------------------------------------------------------+
  570.  
  571.           public ishput?
  572.  
  573. ishput?:  call  ishost?         ; Hostterminal an RS232 ?
  574.           ret   Z               ; nein - immer voll (FALSE zurueck)
  575.           ld    HL,(HOTXCC)     ; Zeichenzaehler Host-FIFO TX = 0 ?
  576.           ld    A,H
  577.           or    L
  578.           ret   Z               ; ja   - FALSE zurueck
  579.           ld    HL,1            ; nein - TRUE zurueck
  580.           ret
  581.  
  582.  
  583.  
  584.  
  585.  
  586. ; +---------------------------------------------------------------------+
  587. ; |                                                                     |
  588. ; | C :  VOID hputc(chr) char chr;   "host put character"               |
  589. ; |                                                                     |
  590. ; | Falls kein Hostterminal an RS232 angeschlossen, Zeichen chr         |
  591. ; | vergessen und Rueckgabe. Sonst Zeichen chr in den Hostterminal-     |
  592. ; | TX-FIFO schreiben, ggf. warten bis Platz im TX-FIFO.                |
  593. ; | Falls TX-FIFO leer war, wird der Interrupt-Zeichensender wieder     |
  594. ; | ange-"kickt".                                                       |
  595. ; |                                                                     |
  596. ; | A, HL, DE benutzt.                                                  |
  597. ; |                                                                     |
  598. ; +---------------------------------------------------------------------+
  599.  
  600.           public hputc?
  601.  
  602. hputc?:   call  ishost?         ; Hostterminal an RS232 ?
  603.           ret   Z               ; nein - Zeichen vergessen, Rueckgabe
  604.           ld    HL,(HOTXCC)     ; ja   - TX-FIFO voll ?
  605.           ld    DE,HOTXFL
  606.           or    A
  607.           sbc   HL,DE
  608.           jr    NC,hputc?       ; ja   - warten bis Platz im TX-FIFO
  609.           ld    HL,2            ; nein - Zeichen als C-Parameter vom Stack
  610.           add   HL,SP           ;        holen
  611.           ld    A,(HL)
  612.           di                    ; keine Ints (keine Zeigerzugriffe) 
  613.           ld    HL,(HOTXCC)     ; TX-FIFO Zeichenzaehler + 1
  614.           inc   HL
  615.           ld    (HOTXCC),HL
  616.           ld    HL,(HOTXIP)     ; Zeiger auf naechste freie Stelle im TX-FIFO
  617.           ld    (HL),A          ; Zeichen in TX-FIFO eintragen
  618.           inc   HL              ; Zeiger auf naechste freie Stelle
  619.           ex    DE,HL
  620.           ld    HL,HOTXFI+HOTXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  621.           or    A                       ; "FIFO Wrap Around" ?
  622.           sbc   HL,DE
  623.           jr    NC,hputc1       ; nein -
  624.           ld    DE,HOTXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  625. hputc1:   ld    (HOTXIP),DE     ; Zeiger abspeichern
  626.           in    A,(SIBCTL)      ; SIO Kanal B (RS232) Tx-Buffer leer ?
  627.           bit   2,A
  628.           call  NZ,HTXFCO       ; ja   - naechstes Zeichen aus TX-FIFO
  629.                                 ;        senden (falls sich kein Zeichen
  630.                                 ;        mehr im TX-FIFO befand, wird
  631.                                 ;        hiermit der Interrupt-Sender wieder
  632.                                 ;        ange-"kickt")
  633.           ei                    ; Interrupts wieder frei
  634.           ret                   ; das war's
  635.  
  636.  
  637.  
  638.  
  639.  
  640. ; +---------------------------------------------------------------------+
  641. ; |                                                                     |
  642. ; | C :  VOID kicktx(port)   unsigned port;                             |
  643. ; |                                                                     |
  644. ; |               port   = 0 :  HDLC-Port (Modem)                       |
  645. ; |                      = 1 :  Crosslink-Port (RS232)                  |
  646. ; |                                                                     |
  647. ; | Sender an-"kicken", d.h. wenn Kanal frei ist, Sendezyklus           |
  648. ; | einleiten, wenn Sender am Frameende des letzten Frames, dann        |
  649. ; | Sender mitteilen, dass noch weitere Frames folgen.                  |
  650. ; |                                                                     |
  651. ; | A, DE, HL benutzt.                                                  |
  652. ; |                                                                     |
  653. ; +---------------------------------------------------------------------+
  654.  
  655.           extrn Dpar?           ; 1 = Vollduplex an
  656.  
  657.           public kicktx?
  658.  
  659. kicktx?:  push  BC              ; C Stackframe-Pointer
  660.           push  IX              ; sichern
  661.           ld    HL,6            ; Zeiger auf C-Uebergabe-Parameter
  662.           add   HL,SP
  663.           ld    A,(HL)          ; Parameter LSB holen, Portnummer
  664.           or    A               ; Kommando fuer Crosslink-Port ?
  665.           jr    NZ,kickt3       ; ja   -
  666.           ld    HL,HTXSTA       ; nein - HDLC-Port
  667.           ld    A,(HL)          ; HDLC-Sender inaktiv ?
  668.           or    A
  669.           jr    Z,kickt1        ; ja   -
  670.           cp    7               ; nein - "in Frame(ende), weitere folgen" ?
  671.           jr    C,kickt9        ; ja   - TX muss nicht ange-"kickt" werden       
  672.           ld    (HL),6          ; nein - "in Frameende, weitere folgen" !
  673.           jr    Z,kickt9        ; wenn nur "in Frameende" war, reicht das 
  674.           ld    A,08h           ; sonst SIO Kanal A (HDLC) "Send Abort" um
  675.           out   (SIACTL),A      ; Flagwirklichzueende-Checkframe zu beenden
  676.           jr    kickt9          ; das war's
  677.  
  678. kickt1:   ld    A,(Dpar?)       ; Vollduplexbetrieb ?
  679.           or    A
  680.           jr    NZ,kickt2       ; ja   - keine DCD-Abfrage
  681.           ld    A,(SIARR0)      ; HDLC-Sender inaktiv, DCD (high, "1") ? 
  682.           bit   3,A
  683.           jr    Z,kickt2
  684.           inc   (HL)            ; ja   - Sendezyklus einleiten, wenn kein
  685.           jr    kickt9          ;        DCD mehr anliegt (TX-State = 1/2)
  686.  
  687. kickt2:   ld    A,1             ; nein - sofort Sendezyklus einleiten
  688.           call  HTXINI          ;        (TX-State = 3)
  689.           jr    kickt9          ;        das war's
  690.  
  691. kickt3:   call  ishost?         ; Hostterminal angeschlossen ?
  692.           jr    NZ,kickt8       ; ja   - alle Crosslink-Frames wegwerfen
  693.           ld    HL,CTXSTA       ; nein - Crosslink-Sender inaktiv ?
  694.           ld    A,(HL)
  695.           or    A
  696.           jr    Z,kickt6        ; ja   -
  697.           cp    10              ; nein - (vor-)letztes Zeichen im Sender ?
  698.           jr    NC,kickt5       ; ja   - direkt neues Frame beginnen
  699.           cp    7               ; nein - TX-State 7 der 9, "Frameende,
  700.           jr    Z,kickt4        ;        keine weiteren folgen" ?
  701.           cp    9
  702.           jr    NZ,kickt9       ; nein - da eh weitere folgen, nix noetig
  703. kickt4:   dec   (HL)            ; ja   - es reicht, dem Sender mitzuteilen,
  704.           jr    kickt9          ;        "weitere folgen" (7/9 -> 6/8)
  705.  
  706. kickt5:   call  CTXSTX          ; neues Crosslink-Frame mit ASCII STX
  707.           jr    kickt9          ; beginnen
  708.  
  709. kickt6:   ld    A,(SIBRR0)      ; Crosslink-Sender inaktiv, Modemstecker DTR 
  710.           bit   5,A             ; high = 1 = Pin /CTS low, d.h. Kanal frei ?
  711.           jr    NZ,kickt7
  712.           inc   (HL)            ; nein - TX-State = 1/2 "Sendezyklus
  713.           jr    kickt9          ;        einleiten, wenn Kanal frei wird"
  714.  
  715. kickt7:   ld    A,1             ; ja   - Crosslink-Sender aktivieren
  716.           call  CTXINI          ;        (TX-State 1 -> 3)
  717.           jr    kickt9          ;        das war's
  718.  
  719. kickt8:   ld    HL,8101h        ; Kommando an Crosslink-TX-Buffer :
  720.           call  GETSRV          ; "alle Frames wegwerfen"
  721.  
  722. kickt9:   pop   IX              ; C Stackframe-Pointer
  723.           pop   BC              ; restaurieren
  724.           ret                   ; das war's endgueltig
  725.  
  726.  
  727.  
  728.  
  729.  
  730. ; +---------------------------------------------------------------------+
  731. ; |                                                                     |
  732. ; | C :  VOID pushtx()                                                  |
  733. ; |                                                                     |
  734. ; | Wenn HDLC-Sender auf Abfall von DCD wartet, sofort auf Sendung      |
  735. ; | gehen (wird gebraucht zur Vermeidung eines Deadlocks bei            |
  736. ; | Umschaltung in den Vollduplex-Betrieb).                             |
  737. ; |                                                                     |
  738. ; | A, DE, HL benutzt.                                                  |
  739. ; |                                                                     |
  740. ; +---------------------------------------------------------------------+
  741.  
  742.           public pushtx?
  743.  
  744. pushtx?:  push  BC              ; C Stackframe-Pointer
  745.           push  IX              ; sichern
  746.           ld    HL,HTXSTA       ; (HL setzen fuer HTXINI)
  747.           ld    A,(HL)          ; TX-State = 1 oder 2, "nachdem Port frei
  748.           or    A               ; wird, senden" ?
  749.           jr    Z,pusht1
  750.           cp    3
  751.           call  C,HTXINI        ; ja - dann Sender sofort hochfahren
  752. pusht1:   pop   IX              ; C Stackframe-Pointer
  753.           pop   BC              ; restaurieren
  754.           ret                   ; das war's
  755.  
  756.  
  757.  
  758.  
  759.  
  760. ; +---------------------------------------------------------------------+
  761. ; |                                                                     |
  762. ; | "SIO channel B Tx Buffer Empty" - Interruptservice                  |
  763. ; |                                                                     |
  764. ; | RS232 SIO TX-Buffer leer, entweder (Hostterminal angeschlossen)     |
  765. ; | Zeichen aus Hostterminal-FIFO falls nicht leer senden oder          |
  766. ; | (Crosslink an RS232) Zeichen aus Frame senden, Frameendebehandlung, |
  767. ; | DLE-Stuffing.                                                       |
  768. ; |                                                                     |
  769. ; |                                                                     |
  770. ; | Crosslink-Frameformat :                                             |
  771. ; |                                                                     |
  772. ; |   +-----+---------         ------+-----+-----+                      |
  773. ; |   | STX | info       ...         | ETX | FCS |                      |
  774. ; |   +-----+---------         ------+-----+-----+                      |
  775. ; |     02h   |                        03h   8 Bit Frame Checksumme,    |
  776. ; |           |                              nur ueber info, ohne 1.    |
  777. ; |           |                              DLE bei "Stuffing"         |
  778. ; |           |                                                         |
  779. ; |           +---> Infobytes, STX in info wird zu DLE STX    DLE = 10h |
  780. ; |                            ETX     "           DLE ETX              |
  781. ; |                            DLE     "           DLE DLE              |
  782. ; |                                                                     |
  783. ; +---------------------------------------------------------------------+
  784.  
  785. SIBTBE:   push  AF              ; Register sichern
  786.           push  BC
  787.           push  DE
  788.           push  HL
  789.           push  IX
  790.           ld    A,28h           ; SIO Kanal B (RS232) Reset Tx Int Pending
  791.           out   (SIBCTL),A
  792.           call  ishost?         ; Hostterminal an RS232 angeschlossen ?
  793.           jr    NZ,SIBT11       ; ja   -
  794.           ld    HL,CTXSTA       ; nein - Crosslink-Kanal
  795.           ld    A,(HL)          ; Crosslink-TX-State :
  796.           sub   5
  797.           jr    Z,SIBT4         ;  5: innerhalb Frame
  798.           jr    C,SIBT12        ;  0: letztes Zeichen aus SIO -> nix tun
  799.           dec   A
  800.           jr    Z,SIBT3         ;  6: Frameende, noch weitere, ETX gesendet
  801.           dec   A
  802.           jr    Z,SIBT3         ;  7: Frameende, keine weiteren, ETX gesendet
  803.           dec   A         
  804.           jr    Z,SIBT2         ;  8: Frameende, noch weitere, FCS gesendet
  805.           dec   A
  806.           jr    Z,SIBT1         ;  9: Frameende, keine weiteren, FCS gesendet
  807.           dec   A
  808.           jr    Z,SIBT1         ; 10: Sendungsende, vorletztes Zeichen fertig
  809.           ld    (HL),0          ; 11: Sendungsende, letztes Zeichen fertig,
  810.           call  CCOFF           ;     TX inaktiv, Crosslink-"Traeger"
  811.           jr    SIBT12          ;     abschalten, das war's
  812.  
  813. SIBT1:    inc   (HL)            ; 9/10 -> 10/11, Zaehler fuer Frameende-
  814.           jr    SIBT10          ; Feststellung, 00h als Dummy an RS232
  815.  
  816. SIBT2:    call  CTXSTX          ; Frameende, noch weitere :  neues Frame
  817.           jr    SIBT12          ; beginnen, das war's
  818.  
  819. SIBT3:    inc   (HL)            ; Frameende, ETX gesendet : TX-State wie
  820.           inc   (HL)            ; vorher, aber "FCS gesendet"
  821.           ld    A,(CTXFCS)      ; Frame-Checksumme
  822.           jr    SIBT10          ; aussenden
  823.  
  824. SIBT4:    ld    HL,CTXCSA       ; kommt jetzt STX/ETX/DLE nach DLE ?
  825.           ld    A,(HL)
  826.           or    A
  827.           jr    Z,SIBT5
  828.           ld    (HL),0          ; ja   - "nach DLE"-Buffer loeschen
  829.           jr    SIBT9           ;        und Zeichen aus Buffer aussenden
  830.  
  831. SIBT5:    ld    HL,0100h        ; nein - Kommando :  "naechstes Zeichen aus
  832.           call  GETSRV          ; TX-Crosslink-Buffer holen" ausfuehren
  833.           ld    A,L             ; Frame zuende ?
  834.           bit   7,H
  835.           jr    Z,SIBT7         ; nein - normales Zeichen
  836.           ld    HL,CTXSTA       ; ja   - TX-State "Frameende, weitere folgen"
  837.           inc   (HL)
  838.           bit   0,A             ; noch weitere Frames vorhanden ?
  839.           jr    Z,SIBT6
  840.           inc   (HL)            ; nein - TX-State "Frameende, keine weiteren"
  841. SIBT6:    ld    A,AETX          ; Frame mit ETX beenden
  842.           jr    SIBT10
  843.  
  844. SIBT7:    cp    ASTX            ; auszusendendes Zeichen STX/ETX/DLE ?
  845.           jr    Z,SIBT8
  846.           cp    AETX
  847.           jr    Z,SIBT8
  848.           cp    ADLE
  849.           jr    NZ,SIBT9
  850. SIBT8:    ld    (CTXCSA),A      ; ja   - entsprechendes Zeichen merken
  851.           ld    A,ADLE          ;        und DLE aussenden
  852.           jr    SIBT10
  853.  
  854. SIBT9:    ld    C,A             ; nein - Zeichen merken
  855.           ld    HL,CTXFCS       ;        Checksumme := Checksumme + Zeichen
  856.           add   A,(HL)
  857.           ld    (HL),A
  858.           ld    A,C             ;        Zeichen restaurieren und senden
  859.  
  860. SIBT10:   out   (SIBDAT),A      ; Zeichen an SIO ausgeben
  861.           jr    SIBT12          ; das war's
  862.  
  863. SIBT11:   call  HTXFCO          ; Zeichen aus Hostterminal-Buffer an RS232
  864.  
  865. SIBT12:   pop   IX              ; Register restaurieren
  866.           pop   HL
  867.           pop   DE
  868.           pop   BC
  869.           pop   AF
  870.           ei                    ; Interrupts wieder erlauben
  871.           reti                  ; das war's
  872.  
  873.  
  874.  
  875.  
  876.  
  877. ; +---------------------------------------------------------------------+
  878. ; |                                                                     |
  879. ; | "SIO channel B External Status Change" - Interruptservice           |
  880. ; |                                                                     |
  881. ; | RS232 DCD Wechsel                                                   |
  882. ; |   DCD ist das Crosslink/Hostterminal-Signal. Ein Wechsel bedeutet   |
  883. ; |   Umschaltung von Hostterminal auf Crosslink oder umgekehrt. Es     |
  884. ; |   werden alle Buffer, FIFO's und Variable fuer Crosslink und        |
  885. ; |   Hostterminal initialisiert. Noch nicht verarbeitete Inhalte       |
  886. ; |   werden weggeworfen. Ggf. wird der Crosslink-"Vorlauftraeger"      |
  887. ; |   abgeschaltet.                                                     |
  888. ; |                                                                     |
  889. ; | SIO Pin /CTS = RS232 Modemstecker DTR Wechsel                       |
  890. ; |   Dies ist das Crosslink-Kanal-"DCD". Ein Wechsel bedeutet den      |
  891. ; |   Wechsel von einem freien auf einen belegten Kanal oder umgekehrt. |
  892. ; |   Geschieht ein Wechsel von besetzt auf frei und der Sender wartete |
  893. ; |   auf freien Kanal, dann wird entsprechend die Sendesequenz         |
  894. ; |   aktiviert ("Vorlauftraeger" oder "Async"-WAIT").                  |
  895. ; |   Geschieht ein Wechsel von frei auf besetzt und der Sender befand  |
  896. ; |   sich im "Async"-WAIT Warten oder im "Vorlauftraeger", dann wird   |
  897. ; |   die Sendesequenz abgebrochen und wieder auf Warten auf freien     |
  898. ; |   Kanal gesetzt, ggf. wird der Crosslink-"Vorlauftraeger"           |
  899. ; |   abgeschaltet.                                                     |
  900. ; |                                                                     |
  901. ; | 1200 Hz SIO Pin SYNC Flanken                                        |
  902. ; |   Dies ist der grundlegende Timer-Interrupt. Hieraus wird der       |
  903. ; |   System-10-msec-Takt abgeleitet. Der Systemtimer wird aufgerufen   |
  904. ; |   und die Senderwartevariablen werden verwaltet. Bei Ablauf wird    |
  905. ; |   entsprechend der Sendesequenz verfahren.                          |
  906. ; |                                                                     |
  907. ; +---------------------------------------------------------------------+
  908.  
  909.           external timer?       ; C Systemtimer (10 msec)
  910.  
  911. SIBESC:   push  AF              ; Register sichern
  912.           push  BC
  913.           push  DE
  914.           push  HL
  915.           push  IX
  916.           in    A,(SIBCTL)      ; Status SIO Kanal B (RS232) holen
  917.           ld    B,A             ; und merken
  918.           ld    A,10H           ; Reset External/Status Interrupts
  919.           out   (SIBCTL),A
  920.           ld    HL,SIBRR0
  921.           ld    A,(HL)          ; alter Status
  922.           ld    (HL),B          ; neuen Status merken
  923.           xor   B
  924.           ld    C,A             ; C = was hat sich geaendert
  925.           bit   3,C             ; Abfrage DCD-Wechsel-Interrupt
  926.           jr    Z,SIBE1
  927.  
  928. ;
  929. ; DCD hat sich geaendert
  930. ;  
  931.           push  BC              ; Status/Statusaenderung merken
  932.           call  HOINIT          ; Hostterminal-FIFO's loeschen,
  933.                                 ; Crosslink-"Traeger" aus
  934.           ld    BC,8101h        ; aktive Crosslink-TX-Buffer in
  935.           call  PUTSRV          ; "Gesendet"-Liste einhaengen
  936.           ld    HL,8101h        ; aktive Crosslink-RX-Buffer
  937.           call  GETSRV          ; auf den Muell werfen
  938.           xor   A               ; Crosslink RX/TX Variable resetten
  939.           ld    (CRXSTA),A
  940.           ld    (CTXSTA),A
  941.           ld    (CTXWAI),A
  942.           pop   BC              ; Status/Statusaenderung restaurieren
  943.  
  944. SIBE1:    bit   5,C             ; Abfrage CTS-Wechsel-Interrupt
  945.           jr    Z,SIBE5
  946.  
  947. ;
  948. ; Pin /CTS = Modemstecker DTR hat sich geaendert
  949. ; (Crosslink-"Traeger" Input)
  950. ;
  951.           push  BC              ; Status/Statusaenderung merken
  952.           ld    HL,CTXSTA
  953.           ld    A,(HL)          ; Pin /CTS low = Modemstecker DTR high =
  954.           bit   5,B             ; Crosslink-Kanal frei zur Sendung ?
  955.           jr    Z,SIBE2         ; nein - ging also von frei auf besetzt
  956.           or    A               ; ja   - Crosslink-TX inaktiv ?
  957.           jr    Z,SIBE4         ; ja   - nix weiter tun
  958.           cp    3               ; nein - auf "Kanal frei" wartend ?
  959.           jr    NC,SIBE4        ; nein - TX muss nicht aktiviert werden
  960.           call  CTXINI          ; ja   - Crosslink-Sendesequenz aktivieren
  961.           jr    SIBE4
  962.  
  963. SIBE2:    sub   3               ; Crosslink-Kanal frei -> besetzt,
  964.           jr    Z,SIBE3         ; "Async"-WAIT Wartezustand (State 3)
  965.           dec   A               ; oder Crosslink-"Vorlauftraeger" (State 4) ? 
  966.           jr    NZ,SIBE4        ; nein - nix weiter tun
  967. SIBE3:    ld    (CTXWAI),A      ; ja   - Wartezaehler inaktivieren ( = 0),
  968.           dec   (HL)            ;        TX-Wartezustand wieder auf Zustand
  969.           dec   (HL)            ;        vor Warten/"Vorlauftraeger"
  970.           bit   1,(HL)          ;        war es "Vorlauftraeger" (4-2=2) ?
  971.           call  NZ,CCOFF        ;        ja - diesen abschalten
  972.  
  973. SIBE4:    pop   BC              ; Status/Statusaenderung restaurieren
  974.  
  975.  
  976. SIBE5:    bit   4,C             ; Abfrage SYNC-Flanken-Interrupt
  977.           jr    Z,SIBE9
  978.  
  979. ;
  980. ; Flanke am Pin SYNC = 1200 Hz Interrupt
  981. ;
  982.           ld    HL,CTXWAI       ; Crosslink TX-Wartezaehler inaktiv ?
  983.           ld    A,(HL)
  984.           or    A
  985.           jr    Z,SIBE7         ; ja   -
  986.           dec   (HL)            ; nein - abgelaufen ?
  987.           jr    NZ,SIBE7        ; nein -
  988.           ld    HL,CTXSTA       ; ja   - war es "Vorlauftraeger" (State 4) ?
  989.           ld    A,(HL)
  990.           cp    4
  991.           jr    Z,SIBE6
  992.           inc   (HL)            ; nein - war "Async"-WAIT, ab jetzt 2,5 msec
  993.           call  CTXPRE          ;        Crosslink-"Vorlauftraeger" (State 4)
  994.           jr    SIBE7
  995. SIBE6:    call  CTXSTX          ; ja   - Frame beginnen
  996.  
  997. SIBE7:    ld    HL,TICDIV       ; 1200 Hz -> 10 msec Teiler abgelaufen ?
  998.           inc   (HL)
  999.           ld    A,(HL)
  1000.           cp    12
  1001.           jr    C,SIBE9         ; nein - dann war's das
  1002.  
  1003. ;
  1004. ; alle 10 msec :
  1005. ;
  1006.           ld    (HL),0          ; ja   - Teiler neu aktivieren
  1007.           call  timer?          ; 10 msec Ticker im Hauptprogamm          
  1008.           ld    HL,HTXWAI       ; HDLC-TX-Wartezaehler aktiv ?
  1009.           ld    A,(HL)
  1010.           or    A
  1011.           jr    Z,SIBE9         ; nein - dann war's das
  1012.           dec   (HL)            ; ja   - abgelaufen ?
  1013.           jr    NZ,SIBE9        ; nein - dann war's das
  1014.           ld    HL,HTXSTA       ; ja   - in TXDELAY ?
  1015.           ld    A,(HL)
  1016.           cp    4
  1017.           jr    Z,SIBE8         ;        ja   - Frame beginnen
  1018.           dec   A               ;        nein - TX-Statezaehler fuer HTXINI
  1019.           dec   A               ;               korrigieren und Sender
  1020.           call  HTXINI          ;               hochfahren
  1021.           jr    SIBE9
  1022.  
  1023. SIBE8:    inc   (HL)
  1024.           call  HTXSOF          ; ja   - Frame beginnen
  1025.  
  1026. SIBE9:    pop   IX              ; Register restaurieren
  1027.           pop   HL
  1028.           pop   DE
  1029.           pop   BC
  1030.           pop   AF
  1031.           ei                    ; Interrupts wieder erlauben
  1032.           reti                  ; das war's
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038. ; +---------------------------------------------------------------------+
  1039. ; |                                                                     |
  1040. ; | "SIO channel B Rx Character Available" - Interruptservice           |
  1041. ; |                                                                     |
  1042. ; | RS232 SIO RX Zeichen da, entweder (Hostterminal angeschlossen)      |
  1043. ; | Zeichen in den Hostterminal-FIFO schreiben falls nicht voll, oder   |
  1044. ; | (Crosslink an RS232) Zeichen in Crosslink-Buffer schreiben,         |
  1045. ; | Frameendebehandlung, DLE-Stuffing.                                  |
  1046. ; |                                                                     |
  1047. ; +---------------------------------------------------------------------+
  1048.  
  1049. SIBRCA:   push  AF              ; Register sichern
  1050.           push  BC
  1051.           push  DE
  1052.           push  HL
  1053.           push  IX
  1054.           in    A,(SIBDAT)      ; Zeichen von RS232 holen
  1055.           ld    C,A
  1056.           call  ishost?         ; Hostterminal angeschlossen ?
  1057.           jr    NZ,SIBR8        ; ja   -
  1058.  
  1059. ;
  1060. ; Crosslink an RS232
  1061. ;
  1062.           ld    HL,CRXSTA       ; nein - Crosslink
  1063.           ld    A,(HL)          ; Crosslink-RX-State :
  1064.           or    A
  1065.           jr    Z,SIBR1         ;  0: RX inaktiv
  1066.           dec   A
  1067.           jr    Z,SIBR3         ;  1: RX aktiv, innerhalb Frame
  1068.           dec   A
  1069.           jr    Z,SIBR5         ;  2: RX aktiv, letztes Zeichen war DLE
  1070.           ld    (HL),0          ;  3: Frameende, Checksumme kommt, (3 -> 0)
  1071.           ld    A,(CRXFCS)      ; RX Checksumme ok ?
  1072.           cp    C
  1073.           ld    BC,8100h        ; (Befehl "Crosslink-RX-Buffer in RX-Liste")
  1074.           jr    Z,SIBR7         ; ja   - Frame ok, in RX-Liste einhaengen
  1075.           inc   C               ; (Befehl "Crosslink-RX-Buffer auf Muell)
  1076.           jr    SIBR7           ; nein - Framebuffer auf den Muell werfen
  1077.  
  1078. SIBR1:    ld    A,C             ; RX inaktiv,
  1079.           cp    ASTX            ; Zeichen = Frameanfang (STX) ? 
  1080.           jr    NZ,SIBR10       ; nein - dann war's das
  1081.           inc   (HL)            ; ja   - RX-State "RX innerhalb Frame" (1)
  1082. SIBR2:    xor   A               ;        RX-Checksumme loeschen
  1083.           ld    (CRXFCS),A
  1084.           ld    BC,8101h        ;        neuen Crosslink-RX-Buffer beginnen
  1085.           jr    SIBR7           ;        das war's
  1086.  
  1087. SIBR3:    ld    A,C             ; RX aktiv, innerhalb Frame,
  1088.           cp    ASTX            ; Zeichen = Frameanfang (STX) ?
  1089.           jr    Z,SIBR2         ; ja   - RX resetten, neues Frame
  1090.           cp    ADLE            ; Zeichen DLE ?
  1091.           jr    Z,SIBR4         ; ja   - RX-State "letztes Zeichen DLE" (2)
  1092.           cp    AETX            ; nein - Zeichen = Frameende (ETX) ?
  1093.           jr    NZ,SIBR6        ; nein - normales Info-Zeichen
  1094.           inc   (HL)            ; ja   - RX-State "Checksumme kommt" (3)
  1095. SIBR4:    inc   (HL)
  1096.           jr    SIBR10          ; das war's
  1097.  
  1098. SIBR5:    dec   (HL)            ; letztes Zeichen war DLE, naechstes Zeichen
  1099.                                 ; (STX/ETX/DLE) ist Info, RX-State 2 -> 1
  1100. SIBR6:    ld    HL,CRXFCS       ; Info-Zeichen
  1101.           ld    A,(HL)          ; auf Checksumme
  1102.           add   A,C             ; addieren
  1103.           ld    (HL),A
  1104.           ld    B,0001h         ; und in Crosslink-RX-Buffer
  1105. SIBR7:    call  PUTSRV          ; Crosslink-RX-Buffer-Verwaltung
  1106.           jr    SIBR10          ; das war's
  1107.  
  1108. ;
  1109. ; Hostterminal an RS232
  1110. ;
  1111. SIBR8:    ld    HL,HORXFL       ; noch Platz im RX-Hostterminal-FIFO, d.h.
  1112.           ld    DE,(HORXCC)     ; Zeichenzaehler + 1 <= FIFO-Laenge ?
  1113.           inc   DE
  1114.           or    A
  1115.           sbc   HL,DE
  1116.           jr    C,SIBR10        ; nein - Zeichen vergessen
  1117.           ld    (HORXCC),DE     ; ja   - Zeichenzaehler + 1 abspeichern
  1118.           ld    HL,(HORXIP)     ; Zeiger auf naechste freie Stelle
  1119.           ld    (HL),C          ; Zeichen in den FIFO einschreiben
  1120.           inc   HL              ; Zeiger auf naechste Stelle
  1121.           ex    DE,HL
  1122.           ld    HL,HORXFI+HORXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  1123.           or    A                       ; "FIFO Wrap Around" ?
  1124.           sbc   HL,DE
  1125.           jr    NC,SIBR9        ; nein -
  1126.           ld    DE,HORXFI       ; ja   - Zeiger auf FIFO-Anfang
  1127. SIBR9:    ld    (HORXIP),DE     ; Zeiger abspeichern
  1128.  
  1129. SIBR10:   pop   IX              ; Register restaurieren
  1130.           pop   HL
  1131.           pop   DE
  1132.           pop   BC
  1133.           pop   AF
  1134.           ei                    ; Interrupts wieder erlauben
  1135.           reti                  ; das war's
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141. ; +---------------------------------------------------------------------+
  1142. ; |                                                                     |
  1143. ; | "SIO channel B Special Receive Condition" - Interruptservice        |
  1144. ; |                                                                     |
  1145. ; | RS232-Fehlerbedingung ruecksetzen. Nicht auswerten - Fehler ist     |
  1146. ; | Fehler und im Kommunikationsablauf passiert nix (Crosslink-Frame    |
  1147. ; | ist eh kaputt, und wen interessierts am Hostterminal,  w a s        |
  1148. ; | passiert ist).                                                      |
  1149. ; |                                                                     |
  1150. ; +---------------------------------------------------------------------+
  1151.  
  1152. SIBSRC:   push  AF              ; benutztes Register sichern
  1153.           ld    A,30h           ; SIO Kanal B (RS232) Error Reset
  1154.           out   (SIBCTL),A      ; (Achselzucken. Kann ja nix passieren.)
  1155.           pop   AF              ; benutztes Register restaurieren
  1156.           ei                    ; Interrupts wieder erlauben
  1157.           reti                  ; das war's
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163. ; +---------------------------------------------------------------------+
  1164. ; |                                                                     |
  1165. ; | "SIO channel A Tx Buffer Empty" - Interruptservice                  |
  1166. ; |                                                                     |
  1167. ; | HDLC SIO TX-Buffer leer, naechstes Zeichen aus HDLC-TX-Framebuffer  |
  1168. ; | holen und senden, wenn innerhalb Frame. Bei Frameende ohne Zeichen- |
  1169. ; | ausgabe in den Underrun/EoM-Interrupt laufen lassen.                |
  1170. ; | Nach einem Underrun/EoM-Interrupt entweder neues Frame beginnen     |
  1171. ; | (es sind noch weitere vorhanden) oder Dummyframe zur Feststellung   |
  1172. ; | des Endes des vorherigen Frames beginnen (keine weiteren mehr       |
  1173. ; | vorhanden). Nachdem ueber das Dummyframe Ende (Flag von vorherigem  |
  1174. ; | Frame hat SIO verlassen) des vorherigen Frames festgestellt wurde,  |
  1175. ; | Sender abschalten.                                                  |
  1176. ; |                                                                     |
  1177. ; +---------------------------------------------------------------------+
  1178.  
  1179.           extrn xFpar?          ; 1 = Flags in Pausen senden, 0 sonst
  1180.  
  1181. SIATBE:   push  AF              ; Register sichern
  1182.           push  BC
  1183.           push  DE
  1184.           push  HL
  1185.           push  IX
  1186.           ld    A,28h           ; SIO Kanal A (HDLC) Reset TX Int Pending
  1187.           out   (SIACTL),A
  1188.           ld    HL,HTXSTA       ; HDLC-TX innerhalb Frame Datenbytes ?
  1189.           ld    A,(HL)
  1190.           sub   5
  1191.           jr    NZ,SIAT1        ; nein -
  1192.           ld    L,A             ; ja   - Zeichen aus HDLC-TX-Framebuffer
  1193.           ld    H,A             ; (HL=0) holen in HL
  1194.           call  GETSRV
  1195.           ld    A,L             ; Zeichen in A
  1196.           bit   7,H             ; Frame zueende ?
  1197.           jr    Z,SIAT4         ; nein - Zeichen an HDLC-Port ausgeben
  1198.           ld    HL,HTXSTA       ; ja   - TX-State "Frameende, weitere folgen"
  1199.           inc   (HL)
  1200.           bit   0,A             ; folgen noch weitere Frames ?
  1201.           jr    Z,SIAT5         ; ja   - dann war's das (ab in Underrum/EoM)
  1202.           inc   (HL)            ; nein - TX-State "Frameende, keine weiteren"
  1203.           jr    SIAT5           ; das war's dann (ab in Underrun/EoM)
  1204.  
  1205. SIAT1:    dec   A               ; TX-State 6 "Frameende, weitere folgen" ?
  1206.           jr    NZ,SIAT2
  1207.           dec   (HL)            ; ja   - TX-State 6 -> 5, "Innerhalb Frame",
  1208.           call  HTXSOF          ;        neues Frame beginnen
  1209.           jr    SIAT5           ;        das war's
  1210.  
  1211. SIAT2:    dec   A               ; nein - TX-State :
  1212.           jr    Z,SIAT3         ;  7: 1. CRC-Byte gesendet, TX-State 7 -> 8,
  1213.                                 ;     Dummyframe zur Feststellung des
  1214.                                 ;     sicheren Endes des vorherigen Frames 
  1215.                                 ;     mit 00h beginnen
  1216.           dec   A
  1217.           jr    Z,SIAT3         ;  8: CRC verlaesst SIO, TX-State 8 -> 9,
  1218.                                 ;     00h an Dummyframe
  1219.           dec   A
  1220.           jr    Z,SIAT3         ;  9: Flag verlaesst SIO, TX-State 9 -> 10,
  1221.                                 ;     00h an Dummyframe
  1222.           dec   A
  1223.           jr    NZ,SIAT5        ; <5: -> ignorieren (Dummyframeende)
  1224.           ld    (HL),A          ; 10: Flag komplett gesendet,
  1225.                                 ;     TX-State 10 -> 0, Sender abschalten
  1226.           ld    A,5             ;     Pin /RTS high = Ptt aus, TX Disable
  1227.           out   (SIACTL),A
  1228.           ld    HL,SIAWR5
  1229.           res   1,(HL)
  1230.           ld    A,(xFpar?)      ;     ( Flags in Pausen ein ?              )
  1231.           or    A
  1232.           jr    NZ,SIAT2a       ;     ( ja   - SIO-TX eingeschaltet lassen )
  1233.           res   3,(HL)          ;     ( nein - SIO-TX ausschalten          )
  1234. SIAT2a:   ld    A,(HL)
  1235.           out   (SIACTL),A      ;     neuen Sendemodus merken
  1236.           ld    A,(Dpar?)       ;     Vollduplex an ?
  1237.           or    A
  1238.           call  Z,HRXRES        ;     nein - HDLC-RX resetten = einschalten
  1239.           jr    SIAT5           ;     das war's
  1240.  
  1241. SIAT3:    inc   (HL)            ; naechster TX-State
  1242. SIAT4:    out   (SIADAT),A      ; Zeichen an SIO
  1243. SIAT5:    pop   IX              ; Register restaurieren
  1244.           pop   HL
  1245.           pop   DE
  1246.           pop   BC
  1247.           pop   AF
  1248.           ei                    ; Interrupts wieder erlauben
  1249.           reti                  ; das war's
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255. ; +---------------------------------------------------------------------+
  1256. ; |                                                                     |
  1257. ; | "SIO channel A External Status Change" - Interruptservice           |
  1258. ; |                                                                     |
  1259. ; | Falls Sender aus und Frameabort empfangen, HDLC-RX resetten, gerade |
  1260. ; | aktives Frame auf den Muell.                                        |
  1261. ; |                                                                     |
  1262. ; | Falls HDLC-TX-Underrun, Frame Abort senden und Frame noch einmal    |
  1263. ; | senden.                                                             |
  1264. ; |                                                                     |
  1265. ; | Falls DCD von an auf aus gewechselt hat und sich Sender in Zustand  |
  1266. ; | "nach DCD aus leite Sendesequenz oder WAIT-Warten ein" befindet,    |
  1267. ; | die naechste Sequenz entsprechend einleiten.                        |
  1268. ; |                                                                     |
  1269. ; | Falls DCD von aus auf an gewechselt hat und sich der Sender in      |
  1270. ; | WAIT-Warte-Sequenz befindet, dann WAIT-Warten abbrechen und nach    |
  1271. ; | naechstem Wechsel an auf aus wieder neu von vorne.                  |
  1272. ; |                                                                     |
  1273. ; +---------------------------------------------------------------------+
  1274.  
  1275. SIAESC:   push  AF              ; Register sichern
  1276.           push  BC
  1277.           push  DE
  1278.           push  HL
  1279.           push  IX
  1280.           in    A,(SIACTL)      ; neuen Status holen
  1281.           ld    B,A             ; B = neuer Status
  1282.           ld    A,10h           ; SIO Kanal A (HDLC) Reset External/Status
  1283.           out   (SIACTL),A      ; Interrupts
  1284.           ld    HL,SIARR0
  1285.           ld    A,(HL)          ; alten Status holen
  1286.           ld    (HL),B          ; neuen Status merken
  1287.           xor   B               ; C = was hat sich geaendert ?
  1288.           ld    C,A
  1289.           ld    HL,HTXSTA       ; TX innerhalb Frame Datenbytes ?
  1290.           ld    A,(HL)
  1291.           cp    5
  1292.           jr    NZ,SIAE1        ; nein -
  1293.           bit   6,B             ; ja   - TX-Underrun ?
  1294.           jr    Z,SIAE1         ; nein - war wohl DCD-Wechsel
  1295.           push  AF
  1296.           push  BC
  1297.           push  HL
  1298.           ld    A,08h           ; ja   - Programm nicht schnell genug, Frame
  1299.           out   (SIACTL),A      ;        "ordentlich" mit Abort beenden,
  1300.           ld    (HL),6          ;        TX-State "letztes Byte aus Frame
  1301.                                 ;        gesendet, weitere Frames folgen",
  1302.           ld    HL,8000h        ;        aktuellen HDLC-TX-Framebuffer 
  1303.           call  GETSRV          ;        "rewinden" = Frame gleich noch
  1304.           pop   HL              ;        einmal probieren
  1305.           pop   BC
  1306.           pop   AF
  1307.  
  1308. SIAE1:    bit   3,C             ; hat DCD gewechselt ?
  1309.           jr    Z,SIAE4         ; nein - dann kann es RX Abort sein
  1310.           push  BC              ; Status sichern
  1311.           bit   3,B             ; DCD angegangen ?
  1312.           jr    NZ,SIAE2        ; ja   -
  1313.           or    A               ; nein - DCD ausgegangen - Sender inaktiv ?
  1314.           jr    Z,SIAE3         ; ja   - DCD-Wechsel ignorieren
  1315.           cp    3               ; nein - TX-State 1 oder 2,
  1316.                                 ;        "TX-Sequenz bei DCD aus einleiten" ? 
  1317.           jr    NC,SIAE3        ; nein - DCD-Wechsel ignorieren
  1318.           call  HTXINI          ; ja   - Sendesequenz einleiten
  1319.           jr    SIAE3
  1320.  
  1321. SIAE2:    cp    3               ; DCD angegangen, waehrend "WAIT abwarten" ?
  1322.           jr    NZ,SIAE3        ; nein - DCD-Wechsel ignorieren
  1323.           ld    A,(Dpar?)       ; ja   - Vollduplex an ?
  1324.           or    A
  1325.           jr    NZ,SIAE3        ; ja   - DCD ignorieren
  1326.           ld    (HL),1          ; nein - Spiel von vorn, TX-State "nachdem
  1327.                                 ;        DCD aus WAIT-Sequenz einleiten",
  1328.           xor   A               ;        Wartezaehler inaktivieren
  1329.           ld    (HTXWAI),A
  1330. SIAE3:    pop   BC              ; Status restaurieren
  1331.  
  1332. SIAE4:    bit   7,C             ; hat HDLC RX ein Abort empfangen ?
  1333.           call  NZ,HRXRE1       ; ja - eingeschalteten Empfaenger resetten
  1334.  
  1335. SIAE5:    pop   IX              ; Register restaurieren
  1336.           pop   HL
  1337.           pop   DE
  1338.           pop   BC
  1339.           pop   AF
  1340.           ei                    ; Interrupts wieder erlauben
  1341.           reti                  ; das war's
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347. ; +---------------------------------------------------------------------+
  1348. ; |                                                                     |
  1349. ; | "SIO channel A Rx Character Available" - Interruptservice           |
  1350. ; |                                                                     |
  1351. ; | Zeichen aus HDLC-Kanal ist angekommen. Ist es das erste Zeichen     |
  1352. ; | eines neuen Frames, dann neuen Framebuffer anlegen, Zeichen merken. |
  1353. ; | Sonst Zeichen merken und vorheriges Zeichen in den Framebuffer      |
  1354. ; | schreiben (vorheriges Zeichen, damit nicht vor dem Anzeigen des     |
  1355. ; | Frameendes CRC-Byte in den Buffer geraet). Bei zu langem Frame      |
  1356. ; | RX resetten und Frame wegwerfen.                                    |
  1357. ; |                                                                     |
  1358. ; +---------------------------------------------------------------------+
  1359.  
  1360. SIARCA:   push  AF              ; Register sichern
  1361.           push  BC
  1362.           push  DE
  1363.           push  HL
  1364.           push  IX
  1365.           in    A,(SIADAT)      ; Zeichen holen SIO Kanal A (HDLC)
  1366.           ld    HL,HRXSTA       ; RX-State = 1, d.h. "Innerhalb Frame" ?
  1367.           inc   (HL)
  1368.           dec   (HL)
  1369.           jr    NZ,SIAR1
  1370.           inc   (HL)            ; nein - "Ausserhalb" -> "Innerhalb Frame"
  1371.           ld    (HRXLCH),A      ;        Zeichen im 1-Zeichen-FIFO merken
  1372.           ld    BC,8001h        ;        neuer HDLC-RX-Buffer
  1373.           call  PUTSRV
  1374.           jr    SIAR2           ;        das war's
  1375.  
  1376. SIAR1:    ld    HL,HRXLCH       ; ja   - "Innerhalb Frame",
  1377.           ld    C,(HL)          ;        altes Zeichen gueltige Info
  1378.           ld    (HL),A          ;        neues altes Zeichen
  1379.           ld    B,0000h         ;        gueltiges Zeichen in den
  1380.           call  PUTSRV          ;        HDLC-RX-Buffer schreiben
  1381.           dec   L               ;        Fehler dabei, d.h. Frame zu lang ?
  1382.           call  Z,HRXRES        ;        ja -> HDLC-RX Reset, Frame wegwerfen
  1383.  
  1384. SIAR2:    pop   IX              ; Register restaurieren
  1385.           pop   HL
  1386.           pop   DE
  1387.           pop   BC
  1388.           pop   AF
  1389.           ei                    ; Interrupts wieder erlauben
  1390.           reti                  ; das war's
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396. ; +---------------------------------------------------------------------+
  1397. ; |                                                                     |
  1398. ; | "SIO channel A Special Receive Condition" - Interruptservice        |
  1399. ; |                                                                     |
  1400. ; | Bei richtigem Frameende (CRC ok, kein Overrun, volle Bytes) wird    |
  1401. ; | Frame in die HDLC-RX-Frameliste eingehaengt, sonst wird das         |
  1402. ; | aktuelle Frame weggeworden.                                         |
  1403. ; |                                                                     |
  1404. ; +---------------------------------------------------------------------+
  1405.  
  1406. SIASRC:   push  AF              ; Register sichern
  1407.           push  BC
  1408.           push  DE
  1409.           push  HL
  1410.           push  IX
  1411.           ld    A,1             ; SIO Kanal A (HDLC) RR1 = Fehlerstatus holen
  1412.           out   (SIACTL),A
  1413.           in    A,(SIACTL)
  1414.           ld    B,A             ; Fehlerstatus sichern
  1415.           ld    A,30h           ; SIO Kanal A (HDLC) Error Reset
  1416.           out   (SIACTL),A
  1417.           ld    A,B             ; Fehlerstatus restaurieren
  1418.           ld    BC,8001h        ; "aktiven HDLC-RX-Framebuffer auf den Muell"
  1419.           bit   5,A             ; RX Overrun ?
  1420.           jr    NZ,SIAS1        ; ja   - Frame wegwerfen
  1421.           bit   7,A             ; End of Frame ?
  1422.           jr    Z,SIAS2         ; nein - nix tun (war "All Sent")
  1423.           bit   6,A             ; CRC Fehler ?
  1424.           jr    NZ,SIAS1        ; ja   - Frame wegwerfen
  1425.           and   0Eh             ; nein - war Frame modulo 8 Bit und letztes
  1426.                                 ;        gueltiges Zeichen vorletztes 
  1427.                                 ;        Zeichen (letztes in Buffer) ?
  1428.           cp    6
  1429.           jr    NZ,SIAS1        ; nein - Frame wegwerfen
  1430.           dec   C               ; ja   - Frame ok, in HDLC-RX-Liste haengen
  1431. SIAS1:    call  HRXNEW          ; Bufferkommando ausfuehren, Frame zuende
  1432.  
  1433. SIAS2:    pop   IX              ; Register restaurieren
  1434.           pop   HL
  1435.           pop   DE
  1436.           pop   BC
  1437.           pop   AF
  1438.           ei                    ; Interrupts wieder erlauben
  1439.           reti                  ; das war's
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445. ; +---------------------------------------------------------------------+
  1446. ; |                                                                     |
  1447. ; | "Hostterminal TX FIFO character out"                                |
  1448. ; |                                                                     |
  1449. ; | Wenn noch Zeichen im Hostterminal-TX-FIFO, dann Zeichen aus diesem  |
  1450. ; | FIFO holen und an RS232 ausgeben.                                   |
  1451. ; |                                                                     |
  1452. ; | A, DE, HL bentzt.                                                   |
  1453. ; |                                                                     |
  1454. ; +---------------------------------------------------------------------+
  1455.  
  1456. HTXFCO:   ld    HL,(HOTXCC)     ; Zeichen in TX-FIFO ?
  1457.           ld    A,H
  1458.           or    L
  1459.           ret   Z               ; nein - nix tun
  1460.           dec   HL              ; ja   - TX-FIFO Zeichenzaehler - 1
  1461.           ld    (HOTXCC),HL
  1462.           ld    HL,(HOTXOP)     ; Zeiger auf Zeichen
  1463.           ld    A,(HL)          ; Zeichen holen
  1464.           out   (SIBDAT),A      ; an SIO Kanal B (RS232) ausgeben
  1465.           inc   HL              ; Zeiger auf naechstes Zeichen
  1466.           ex    DE,HL
  1467.           ld    HL,HOTXFI+HOTXFL-1      ; Zeiger > letzte FIFO-Stelle, d.h.
  1468.           or    A                       ; "FIFO Wrap Around" ?
  1469.           sbc   HL,DE
  1470.           jr    NC,HTXFC1       ; nein -
  1471.           ld    DE,HOTXFI       ; ja   - Zeiger wieder auf FIFO-Anfang
  1472. HTXFC1:   ld    (HOTXOP),DE     ; Zeiger abspeichern
  1473.           ret                   ; das war's
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479. ; +---------------------------------------------------------------------+
  1480. ; |                                                                     |
  1481. ; | CTXINI   "Crosslink TX initialize"                                  |
  1482. ; |   Sender initialisieren, ggf. mit "Async"-WAIT.                     |
  1483. ; |   A = 1  ->  Sender mit "Async"-WAIT initialiseren                  |
  1484. ; |   A = 2  ->  Sender ohne "Async"-WAIT initialisieren, gleich zu     |
  1485. ; |              CTXPRE                                                 |
  1486. ; |                                                                     |
  1487. ; | CTXPRE   "Crosslink TX preset"                                      |
  1488. ; |   2,5 msec Crosslink-"Vorlauftraeger" setzen.                       |
  1489. ; |                                                                     |
  1490. ; | CTXSTX   "Crosslink TX start of text"                               |
  1491. ; |   Crosslinkframe beginnen mit ASCII Start of Text.                  |
  1492. ; |                                                                     |
  1493. ; | A, DE, HL benutzt.                                                  |
  1494. ; |                                                                     |
  1495. ; +---------------------------------------------------------------------+
  1496.  
  1497. CTXINI:   inc   A               ; naechster Sendestatus 1/2 -> 3/4
  1498.           inc   A
  1499.           ld    HL,CTXSTA
  1500.           ld    (HL),A
  1501.           cp    4               ; erstes Frame zu digipeatendes Frame ?
  1502.           jr    Z,CTXPRE        ; nein - kein "Async"-WAIT
  1503.           call  random?         ; ja   - "Async"-WAIT beachten
  1504.           and   1Fh             ;        3 < A < 32 = 2,5 msec ... 25 msec
  1505.           or    03h             ;        (1200Hz/3 ... 1200Hz/32)
  1506.           ld    (CTXWAI),A
  1507.           ret
  1508.  
  1509. CTXPRE:   ld    A,5             ; 2,5 msec Crosslink-"Vorlauftraeger" setzen
  1510.           out   (SIBCTL),A
  1511.           ld    HL,SIBWR5
  1512.           res   1,(HL)          ; "/RTS high after TX empty" -> /RTS high
  1513.           ld    A,(HL)          ; = Modemstecker CTS low
  1514.           out   (SIBCTL),A      ; = Crosslink-"Traeger" ein
  1515.           ld    A,3             ; 2,5 msec (1200Hz/3)
  1516.           ld    (CTXWAI),A
  1517.           ret                   ; das war's
  1518.  
  1519. CTXSTX:   ld    (HL),5          ; Sendestatus "Innerhalb Crosslink-Frame"
  1520.           xor   A
  1521.           ld    (CTXFCS),A      ; Sende-Framechecksumme initialisieren
  1522.           ld    (CTXCSA),A      ; "kein STX/ETX/DLE innerhalb Frame"
  1523.           ld    A,ASTX          ; Frame beginnt mit ASCII STX,
  1524.           out   (SIBDAT),A      ; Interruptsender an-"kicken"
  1525.           ret                   ; das war's
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531. ; +---------------------------------------------------------------------+
  1532. ; |                                                                     |
  1533. ; | HOINIT   "Host initialize"                                          |
  1534. ; |   Alle Hostterminal-FIFO's (RX und TX) resetten, Crosslink-         |
  1535. ; |   "Traeger" ausschalten.                                            |
  1536. ; |                                                                     |
  1537. ; | CCOFF   "Crosslink carrier off"                                     |
  1538. ; |   Crosslink-"Traeger" ausschalten = Pin /RTS low = Modemstecker     |
  1539. ; |   CTS high.                                                         |
  1540. ; |                                                                     |
  1541. ; | A, HL benutzt.                                                      |
  1542. ; |                                                                     |
  1543. ; +---------------------------------------------------------------------+
  1544.  
  1545. HOINIT:   ld    HL,0
  1546.           ld    (HORXCC),HL     ; alle Hostterminal-FIFO's resetten
  1547.           ld    (HOTXCC),HL
  1548.           ld    HL,HORXFI
  1549.           ld    (HORXIP),HL
  1550.           ld    (HORXOP),HL
  1551.           ld    HL,HOTXFI
  1552.           ld    (HOTXIP),HL
  1553.           ld    (HOTXOP),HL
  1554.  
  1555. CCOFF:    ld    A,5             ; SIO Kanal B (RS232)
  1556.           out   (SIBCTL),A
  1557.           ld    HL,SIBWR5       ; Pin /RTS low = Modemstecker CTS high
  1558.           set   1,(HL)          ;              = Crosslink-"Traeger aus"
  1559.           ld    A,(HL)
  1560.           out   (SIBCTL),A
  1561.           ret
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567. ; +---------------------------------------------------------------------+
  1568. ; |                                                                     |
  1569. ; | HTXINI   "HDLC TX initialize"                                       |
  1570. ; |   Sender initialisieren, ggf. mit WAIT.                             |
  1571. ; |   A = 1  ->  Sender mit WAIT initialiseren                          |
  1572. ; |   A = 2  ->  Sender ohne WAIT initialisieren, gleich zu HTXKUP      |
  1573. ; |                                                                     |
  1574. ; | HTXKUP   "HDLC TX key up"                                           |
  1575. ; |   HDLC RX abschalten, Sender einschalten, PTT ein, TXDELAY starten. |
  1576. ; |                                                                     |
  1577. ; | HTXSOF   "HDLC TX start of frame"                                   |
  1578. ; |   Zeichen aus TX-Framebuffer holen und mit diesem Zeichen neues     |
  1579. ; |   Frame beginnen.                                                   |
  1580. ; |                                                                     |
  1581. ; | A, DE, HL benutzt.                                                  |
  1582. ; |                                                                     |
  1583. ; +---------------------------------------------------------------------+
  1584.  
  1585.           extrn Wpar?           ; WAIT-Parameter in 10 msec
  1586.           extrn Ppar?           ; P-Persistenz-Wert
  1587.           extrn Tpar?           ; TXDELAY-Parameter in 10 msec
  1588.  
  1589. HTXINI:   inc   A               ; naechster Sendestatus 1/2 -> 3/4
  1590.           inc   A
  1591.           ld    (HL),A
  1592.           cp    4               ; erstes Frame zu digipeatendes Frame ?
  1593.           jr    Z,HTXKUP        ; ja   - kein WAIT beachten
  1594.           ld    A,(Dpar?)       ; nein - Vollduplexbetrieb ?
  1595.           or    A
  1596.           jr    NZ,HTXIN1       ; ja   - Sender sofort hochfahren
  1597.           push  HL              ; nein - (Zeiger auf HTXSTA sichern)
  1598.           call  random?         ; Zufallszahl <= P-Persistenz-Wert ?
  1599.           ld    A,(Ppar?)
  1600.           cp    L
  1601.           pop   HL              ; (Zeiger auf HTXSTA wiedereinsetzen)
  1602.           jr    NC,HTXIN1       ; ja   - Sender hochfahren
  1603.           ld    A,(Wpar?)       ; nein - Slottime abwarten
  1604.           ld    (HTXWAI),A
  1605.           or    A               ; falls Slottime = 0 gleich weiter
  1606.           ret   NZ
  1607.  
  1608. HTXIN1:   inc   (HL)            ; TX-State 3 -> 4
  1609. HTXKUP:   ld    A,(Dpar?)       ; Vollduplexbetrieb ?
  1610.           or    A
  1611.           jr    NZ,HTXKU0
  1612.           ld    A,3             ; nein - "RX disable" = HDLC-Empfaenger
  1613.           out   (SIACTL),A      ;        abschalten
  1614.           ld    A,(SIAIW3)
  1615.           res   0,A
  1616.           out   (SIACTL),A
  1617. HTXKU0:   ld    A,5             ; "TX enable", Pin /RTS low =
  1618.           out   (SIACTL),A      ; HDLC-Sender einschalten, PTT ein
  1619.           ld    HL,SIAWR5
  1620.           set   3,(HL)
  1621.           set   1,(HL)
  1622.           ld    A,(HL)
  1623.           out   (SIACTL),A      ; (geaenderten Sende-Modus merken)
  1624.           ld    A,(Tpar?)       ; TXDELAY in Wartezaehler
  1625.           ld    (HTXWAI),A
  1626.           or    A               ; TXDELAY-Parameter > 0 ?
  1627.           ret   NZ              ; ja   - TXDELAY abwarten
  1628.           ld    HL,HTXSTA       ; nein - kein TXDELAY (TX State = 5)
  1629.           inc   (HL)
  1630. HTXSOF:   ld    HL,0            ; "Zeichen holen aus HDLC-TX-Framebuffer"
  1631.           call  GETSRV          ; Zeichen holen in L
  1632.           ld    A,80h           ; "Reset HDLC TX CRC Generator"
  1633.           out   (SIACTL),A
  1634.           ld    A,L             ; Zeichen ausgeben, erstes Zeichen in Frame,
  1635.           out   (SIADAT),A      ; dadurch Interrupt-Sender ange-"kickt"
  1636.           ld    A,0C0h          ; "Reset HDLC TX Underrun/EoM Latch",
  1637.           out   (SIACTL),A      ; damit Frameende erkannt werden kann
  1638.           ret                   ; das war's
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644. ; +---------------------------------------------------------------------+
  1645. ; |                                                                     |
  1646. ; | "get service"                                                       |
  1647. ; |                                                                     |
  1648. ; | l1get-Aufruf mit HL als Parameter, Ergebnis in HL zurueck.          |
  1649. ; | Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt-       |
  1650. ; | verbietungsstufe beibehalten wird,  o h n e  ggf. ein EI bei        |
  1651. ; | l1get-Aufruf auszuloesen.                                           |
  1652. ; |                                                                     |
  1653. ; | l1get ist die TX-Buffer-Verwaltung, Zeichen holen, Kommandos zur    |
  1654. ; | Bufferbehandlung, Meldungen zum Bufferzustand.                      |
  1655. ; |                                                                     |
  1656. ; | A, DE benutzt.                                                      |
  1657. ; |                                                                     |
  1658. ; +---------------------------------------------------------------------+
  1659.  
  1660.           external l1get?       ; C TX-Buffer-Verwaltung
  1661.  
  1662. GETSRV:   push  HL              ; Aufrufparameter fuer C-Routine l1get
  1663.           ld    HL,DEICNT       ; zu fruehes EI durch l1get verhindern
  1664.           inc   (HL)
  1665.           call  l1get?          ; C-Routine l1get ausfuehren
  1666.           ex    DE,HL           ; Ergebnis von l1get in DE
  1667.           ld    HL,DEICNT       ; wieder alte Interrupt-Verbietungsstufe
  1668.           dec   (HL)
  1669.           ex    DE,HL           ; Ergebnis von l1get in HL
  1670.           pop   DE              ; Stack korrigieren (l1get Parameter)
  1671.           ret                   ; das war's
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677. ; +---------------------------------------------------------------------+
  1678. ; |                                                                     |
  1679. ; | HRXRES   "HDLC RX Reset"                                            |
  1680. ; |   HDLC RX neu anfangen lassen, SIO und Buffer initialisieren.       |
  1681. ; |                                                                     |
  1682. ; | HRXRE1                                                              |
  1683. ; |   Wie HRXRES, aber SIO in Ruhe lassen, nur Buffer initialisieren.   |
  1684. ; |                                                                     |
  1685. ; | HRXNEW   "HDLC RX New"                                              |
  1686. ; |   Wie PUTSRV, am Frameende. Restzeichen aus SIO entfernen,          |
  1687. ; |   Empfangsstatus initialiseren fuer naechstes Frame.                |
  1688. ; |                                                                     |
  1689. ; | PUTSRV   "put service"                                              |
  1690. ; |   l1put-Aufruf mit BC als Parameter, Ergebnis in HL zurueck.        |
  1691. ; |   Auch von innerhalb Interruptroutinen aufrufbar, da Interrupt-     |
  1692. ; |   verbietungsstufe beibehalten wird,  o h n e  ggf. ein EI bei      |
  1693. ; |   l1get-Aufruf auszuloesen.                                         |
  1694. ; |                                                                     |
  1695. ; | l1put ist die RX-Buffer-Verwaltung, Zeichen schreiben, Kommandos    |
  1696. ; | zur Bufferbehandlung, Meldungen zum Bufferzustand.                  |
  1697. ; |                                                                     |
  1698. ; | A, BC, DE benutzt.                                                  |
  1699. ; |                                                                     |
  1700. ; +---------------------------------------------------------------------+
  1701.  
  1702.           external l1put?       ; C RX-Buffer-Verwaltung
  1703.  
  1704. HRXRES:   ld    A,03h           ; SIO Kanal A, RX CRC enable, CRC enable,
  1705.           out   (SIACTL),A      ; Hunt Phase (initiales WR3)
  1706.           ld    A,(SIAIW3)
  1707.           out   (SIACTL),A
  1708. HRXRE1:   ld    BC,8001H        ; aktiven RX-Framebuffer auf den Muell,
  1709.                                 ; wenn nicht leer, sonst neuen beginnen
  1710. HRXNEW:   in    A,(SIADAT)      ; Zeichen aus HDLC-Kanal holen und vergessen
  1711.           xor   A               ; HDLC RX-State : "RX ausserhalb Frame"
  1712.           ld    (HRXSTA),A
  1713. PUTSRV:   push  BC              ; Aufrufparameter fuer l1put
  1714.           ld    HL,DEICNT       ; zu fruehes EI durch l1put verhindern
  1715.           inc   (HL)
  1716.           call  l1put?          ; C-Routine l1put ausfuehren
  1717.           ex    DE,HL           ; l1put-Returnwert merken
  1718.           ld    HL,DEICNT       ; wieder alte Interrupt-Verbietungsstufe
  1719.           dec   (HL)
  1720.           ex    DE,HL           ; l1put-Returnwert restaurieren
  1721.           pop   BC              ; Stack korrigieren (l1put Parameter) 
  1722.           ret                   ; das war's
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728. ; +---------------------------------------------------------------------+
  1729. ; |                                                                     |
  1730. ; | C :  BOOLEAN iscd(port) unsigned port;   "is carrier detect"        |
  1731. ; |                                                                     |
  1732. ; | Test, ob Port (Kanal) mit Nummer port belegt ist (d.h. nicht        |
  1733. ; | gesendet werden darf).                                              |
  1734. ; |                                                                     |
  1735. ; |   port = 0 :  HDLC Modemport                                        |
  1736. ; |        = 1 :  RS232 Crosslinkport                                   |
  1737. ; |                                                                     |
  1738. ; |                                                                     |
  1739. ; | TRUE   -  (HL=1, Z=0) Kanal ist belegt                              |
  1740. ; |                                                                     |
  1741. ; | FALSE  -  (HL=0, Z=1) Kanal ist frei (oder Vollduplex-HDLC)         |
  1742. ; |                                                                     |
  1743. ; |                                                                     |
  1744. ; | A benutzt, HL Returnwert.                                           |
  1745. ; |                                                                     |
  1746. ; +---------------------------------------------------------------------+
  1747.  
  1748.           public iscd?
  1749.  
  1750. iscd?:    ld    HL,2            ; Portnummer als 16-Bit-C-Parameter vom
  1751.           add   HL,SP           ; Stack holen
  1752.           ld    A,(HL)
  1753.           ld    HL,0            ; default Returnwert FALSE
  1754.           dec   A               ; Crosslink-Port (RS232), d.h. 1 ?
  1755.           jr    NZ,iscd2        ; nein -
  1756.  
  1757. ;
  1758. ; Crosslink-Port
  1759. ;
  1760.           ld    A,(SIBRR0)      ; ja   - SIO Kanal B Status holen
  1761.           and   00100000b       ; Pin /CTS low = Modem DTR high ("1") ?
  1762.           jr    NZ,iscd1
  1763.           inc   A               ; nein - H=1, Z=0, TRUE zurueck
  1764.           ld    L,A             ;        (Kanal belegt)
  1765.           ret
  1766. iscd1:    xor   A               ; ja   - H=0, Z=1, FALSE zurueck
  1767.           ret                   ;        (Kanal frei)
  1768.  
  1769. ;
  1770. ; HDLC-Port
  1771. ;
  1772. iscd2:    ld    A,(Dpar?)       ; Vollduplexbetrieb ?
  1773.           dec   A
  1774.           ret   Z               ; ja - Z = 1, A = 0, HL = 0, FALSE
  1775.           ld    A,(SIARR0)      ; SIO Kanal A Status holen
  1776.           bit   3,A             ; SIO Kanal A DCD an ?
  1777.           ret   Z               ; nein - FALSE zurueck (Kanal frei)
  1778.           inc   HL              ; ja   - TRUE zurueck (Kanal belegt)
  1779.           ret
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785. ; +---------------------------------------------------------------------+
  1786. ; |                                                                     |
  1787. ; | C :  BOOLEAN ishost()   "is host terminal"                          |
  1788. ; |                                                                     |
  1789. ; | Rueckgabe :   TRUE,  HL = 1, Z = 0  -  Hostterminal an RS232        |
  1790. ; |               FALSE, HL = 0, Z = 1  -  Crosslink an RS232           |
  1791. ; |                                                                     |
  1792. ; | A benutzt.                                                          |
  1793. ; |                                                                     |
  1794. ; +---------------------------------------------------------------------+
  1795.  
  1796.           public ishost?
  1797.  
  1798. ishost?:  ld    HL,0            ; Rueckgabe-Preset FALSE
  1799.           ld    A,(SIBRR0)      ; DCD an RS232 (SIO Kanal B) ?
  1800.           and   00001000b
  1801.           ret   Z               ; nein - FALSE zurueck (Crosslink)
  1802.           inc   HL              ; ja   - TRUE zurueck  (Hostterminal)
  1803.           ret                   ; das war's
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809. ; +---------------------------------------------------------------------+
  1810. ; |                                                                     |
  1811. ; | C :  char *minmem()   "minimum memory"                              |
  1812. ; |                                                                     |
  1813. ; | Niedrigste nutzbare RAM-Freispeicherstelle in HL zurueck,           |
  1814. ; | Test auf 0 fuer C-Kompatibilitaet.                                  |
  1815. ; |                                                                     |
  1816. ; | A benutzt.                                                          |
  1817. ; |                                                                     |
  1818. ; +---------------------------------------------------------------------+
  1819.  
  1820.           public minmem?
  1821.  
  1822.           external fremem?      ; erste Speicherstelle Freispeicher
  1823.  
  1824. minmem?:  ld    HL,fremem?      ; niedrigste nutzbare RAM-Freispeicherstelle
  1825.           ld    A,H             ; als C-Funktionswert zurueck
  1826.           or    L
  1827.           ret                   ; das war's
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833. ; +---------------------------------------------------------------------+
  1834. ; |                                                                     |
  1835. ; | C :  char *maxmem()   "maximum memory"                              |
  1836. ; |                                                                     |
  1837. ; | Hoechste nutzbare RAM-Freispeicherstelle in HL zurueck,             |
  1838. ; | Test auf 0 fuer C-Kompatibilitaet.                                  |
  1839. ; |                                                                     |
  1840. ; | A benutzt.                                                          |
  1841. ; |                                                                     |
  1842. ; +---------------------------------------------------------------------+
  1843.  
  1844.           public maxmem?
  1845.  
  1846. maxmem?:  ld    HL,(RAMTOP)     ; hoechste nutzbare RAM-Freispeicherstelle
  1847.           ld    A,H             ; als C-Funktionswert zurueck
  1848.           or    L
  1849.           ret                   ; das war's
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855. ; +---------------------------------------------------------------------+
  1856. ; |                                                                     |
  1857. ; | C :  VOID DIinc()   "disable interrupt increment"                   |
  1858. ; |                                                                     |
  1859. ; | Interrupts verbieten, Verbietungsstufe erhoehen.                    |
  1860. ; |                                                                     |
  1861. ; |                                                                     |
  1862. ; | HL benutzt.                                                         |
  1863. ; |                                                                     |
  1864. ; +---------------------------------------------------------------------+
  1865.  
  1866.           public DIinc?
  1867.  
  1868. DIinc?:   di                    ; Interrupts verbieten
  1869.           ld    HL,DEICNT       ; auf die naechste Verbietungsstufe
  1870.           inc   (HL)
  1871.           ret                   ; das war's
  1872.  
  1873.  
  1874.  
  1875.  
  1876.  
  1877. ; +---------------------------------------------------------------------+
  1878. ; |                                                                     |
  1879. ; | C :  VOID decEI()   "decrement enable interrupt"                    |
  1880. ; |                                                                     |
  1881. ; | Verbietungsstufe erniedrigen, wenn dann gleich 0, Interrupts        |
  1882. ; | wieder erlauben.                                                    |
  1883. ; |                                                                     |
  1884. ; | HL benutzt.                                                         |
  1885. ; |                                                                     |
  1886. ; +---------------------------------------------------------------------+
  1887.  
  1888.           public decEI?
  1889.  
  1890. decEI?:   ld    HL,DEICNT       ; Verbietungsstufe - 1
  1891.           dec   (HL)            ; Erlaubnis erreicht ?
  1892.           ret   NZ              ; nein - dann war's das
  1893.           ei                    ; ja   - Interrupts wieder erlauben
  1894.           ret                   ; das war's
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900. ; +---------------------------------------------------------------------+
  1901. ; |                                                                     |
  1902. ; | C :  BOOLEAN CONled(on)   BOOLEAN on;   "CONNECT-LED"               |
  1903. ; |                                                                     |
  1904. ; | Ein- oder Ausschalten der CONNECT-LED.                              |
  1905. ; |                                                                     |
  1906. ; | Parameter :  on = TRUE,  1   ->   LED anschalten                    |
  1907. ; |              on = FALSE, 0   ->   LED ausschalten                   |
  1908. ; |                                                                     |
  1909. ; | A, HL benutzt.                                                      |
  1910. ; |                                                                     |
  1911. ; +---------------------------------------------------------------------+
  1912.  
  1913.           public CONled?
  1914.  
  1915. CONled?:  di                    ; Int's duerfen nicht dazwischenfunken
  1916.           ld    A,5             ; /DTR-Pin = LED-Ausgang wird ueber SIO
  1917.           out   (SIBCTL),A      ; Register 5 angesteuert
  1918.           ld    HL,2            ; Zeiger auf Parameter
  1919.           add   HL,SP
  1920.           ld    A,(HL)          ; Parameter low Byte holen
  1921.           rrca                  ; Bit 0 -> Bit 7
  1922.           xor   80h             ; Bit 0-6 loeschen, Bit 7 invertieren
  1923.           ld    HL,SIBWR5
  1924.           res   7,(HL)          ; SIO B /DTR Pin entsprechend Parameter
  1925.           or    (HL)            ; (on = TRUE -> Pin /DTR low -> LED ein)
  1926.           ld    (HL),A
  1927.           out   (SIBCTL),A      ; selbiges auch merken
  1928.           ei                    ; Interrupts wieder erlauben
  1929.           ret                   ; das war's
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935. ; +---------------------------------------------------------------------+
  1936. ; |                                                                     |
  1937. ; | C :  BOOLEAN STAled(on)   BOOLEAN on;   "STATUS-LED"                |
  1938. ; |                                                                     |
  1939. ; | Ein- oder Ausschalten der STATUS-LED.                               |
  1940. ; |                                                                     |
  1941. ; | Parameter :  on = TRUE,  1   ->   LED anschalten                    |
  1942. ; |              on = FALSE, 0   ->   LED ausschalten                   |
  1943. ; |                                                                     |
  1944. ; | A, HL benutzt.                                                      |
  1945. ; |                                                                     |
  1946. ; +---------------------------------------------------------------------+
  1947.  
  1948.           public STAled?
  1949.  
  1950. STAled?:  di                    ; Int's duerfen nicht dazwischenfunken
  1951.           ld    A,5             ; /DTR-Pin = LED-Ausgang wird ueber SIO
  1952.           out   (SIACTL),A      ; Register 5 angesteuert
  1953.           ld    HL,2            ; Zeiger auf Parameter
  1954.           add   HL,SP
  1955.           ld    A,(HL)          ; Parameter low Byte holen
  1956.           rrca                  ; Bit 0 -> Bit 7
  1957.           xor   80h             ; Bit 0-6 loeschen, Bit 7 invertieren
  1958.           ld    HL,SIAWR5
  1959.           res   7,(HL)          ; SIO A /DTR Pin entsprechend Parameter
  1960.           or    (HL)            ; (on = TRUE -> Pin /DTR low -> LED ein)
  1961.           ld    (HL),A
  1962.           out   (SIACTL),A      ; selbiges auch merken
  1963.           ei                    ; Interrupts wieder erlauben
  1964.           ret                   ; das war's
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970. ; +---------------------------------------------------------------------+
  1971. ; |                                                                     |
  1972. ; | C :  VOID srand()                                                   |
  1973. ; |                                                                     |
  1974. ; | Zufallszahlengenerator initialisieren.                              |
  1975. ; |                                                                     |
  1976. ; +---------------------------------------------------------------------+
  1977.  
  1978.           public srand?
  1979.  
  1980. srand?:   ld    A,R             ; 0 <= A <=127 (oder 128 <= A <= 255)
  1981.           ld    L,A             ; URAND = A
  1982.           ld    H,0
  1983.           ld    (URAND),HL
  1984.           ret
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990. ; +---------------------------------------------------------------------+
  1991. ; |                                                                     |
  1992. ; | C :  unsigned random()                                              |
  1993. ; |                                                                     |
  1994. ; | 8-Bit Quasi-Zufallszahl (0..255) holen in A und HL.                 |
  1995. ; |                                                                     |
  1996. ; +---------------------------------------------------------------------+
  1997.  
  1998.           public random?
  1999.  
  2000. random?:  ld    HL,(URAND)      ; URAND rueckgekoppelt linksschieben
  2001.           ld    A,H             ; (Zweck: Gleichverteilung random())
  2002.           and   01100000b
  2003.           jp    PO,rand1
  2004.           scf
  2005. rand1:    adc   HL,HL
  2006.           ld    (URAND),HL
  2007.           ld    A,R             ; 0 <= A <=127 (oder 128 <= A <= 255)
  2008.           add   A,A             ; 0 <= A <= 254, gerade
  2009.           inc   A               ; 1 <= A <= 255, ungerade
  2010.           xor   L               ; 0 <= A <= 255
  2011.           ld    L,A             ; HL = A
  2012.           ld    H,0             ; (nur LSB signifikant)
  2013.           ret                   ; das war's
  2014.  
  2015.  
  2016.  
  2017.           end
  2018.  
  2019.