home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / packet / mulrpt.lbr / HDLSIO.MZC / HDLSIO.MAC
Text File  |  1985-11-24  |  12KB  |  447 lines

  1.     TITLE    HDLSIO - Z80 SIO HDLC DRIVER ROUTINES
  2.  
  3. ;  Driver routines to operate a port of a Zilog Z80-SIO 
  4. ;  in the SDLC/HDLC mode for packet radio operations.  These
  5. ;  routines operate in the half-duplex mode.  The SIO RTS
  6. ;  line is used to turn the transmitter on.  Transmission
  7. ;  of data will not begin until the SIO CTS line is asserted.
  8. ;
  9. ;  Interface to the main program is via subroutine calls.
  10. ;  Each call must be made with the address of the SIO data
  11. ;  structure in the IY register.  This data structure is
  12. ;  as follows:
  13.  
  14.     INCLUDE    STRUCT.LIB
  15.  
  16. ;  Upon activation, the main program should call the HDLINT
  17. ;  initialization entry point to set up the SIO hardware.
  18. ;  It is only necessary to call this routine once per
  19. ;  SIO channel used.  This routine is called only after a
  20. ;  hardware reset as the routines will take care of all
  21. ;  further SIO setup and disabling for the proper mode (Tx
  22. ;  or Rx).  When frame data is received, the external sub-
  23. ;  routine NEXTHI will be called to accept each data byte
  24. ;  or to flag the end of frame.  When transmission is
  25. ;  desired, the TXSKED entry point must be called to
  26. ;  schedule the transmission.  As each data byte is
  27. ;  required by the SIO transmitter, the external sub-
  28. ;  routine NEXTHO will be called.  When this subroutine
  29. ;  indicates the end of the data for the current transmission,
  30. ;  the transmission will be terminated and the SIO placed
  31. ;  back in receive mode.  The external subroutine HODONE will
  32. ;  then be called.
  33.  
  34.     PAGE
  35. ;  All routines must be entered with the data structure address
  36. ;  in IY.  IX and IY registers are not affected by any of these
  37. ;  routines.  All external subroutines should return with IY
  38. ;  unchanged.
  39. ;
  40. ;  ENTRY POINTS:
  41. ;
  42. ;    HDLI -    Initialization subroutine.  The SIO registers
  43. ;        will be initialized in the receive mode.  CDS
  44. ;        will be called.
  45. ;    Entry:    No parameters.
  46. ;    Return:    All registers undefined.
  47. ;
  48. ;    XSKED -    Schedule transmission.
  49. ;    Entry:    A  = 0 if CW id only
  50. ;           = 1 if frame data to transmit
  51. ;    Return:    all registers undefined
  52. ;
  53. ;    CDS -    Carrier detect status reporting.
  54. ;    Entry:    No parameters required
  55. ;    Return:    A  = 0 if DCD off
  56. ;        A  = 0FFH if DCD on
  57.  
  58. ;  EXTERNAL ROUTINES
  59. ;
  60. ;  All of these routines are called within interrupt service.
  61. ;  External routines may destroy any registers except IY
  62. ;  and those specified below with return parameters.
  63. ;
  64. ;    NXTHO -    Routine to supply next data byte for trans-
  65. ;        mission.
  66. ;    Entry:    No parameters
  67. ;    Return:    A  = 0FFH if next data byte
  68. ;           = 0 if end of message (more to follow)
  69. ;           = 1 if end of transmission (no CW id)
  70. ;           = 2 if end of transmission and id request
  71. ;        B  = next data byte (if A = 0FFH)
  72. ;
  73. ;    ODONE -    Routine at end of transmission.  Called after
  74. ;        receive mode is re-entered.  No parameters.
  75. ;
  76. ;    NXTHI -    Routine to accept received data.  All data
  77. ;        after a call with A = 0 is invalid if another
  78. ;        call with A = 0 occurs before a call with
  79. ;        A = 1.
  80. ;    Entry:    A  = 0FFH if next data byte
  81. ;        A  = 0 if start of frame
  82. ;        A  = 1 if end of frame
  83. ;        B  = next data byte (if A = 0 or 0FFH)
  84. ;    Return:    No parameters
  85.  
  86.     PAGE
  87.     .Z80
  88.  
  89. ;  SIO constants
  90.  
  91.             ;COMMANDS:
  92. RESTXI    EQU    28H        ;Reset TX interrupt
  93. RESEXT    EQU    10H        ;Reset external interrupt
  94. RESTCR    EQU    80H        ;Reset TX CRC generator
  95. RESEOM    EQU    0C0H        ;Reset TX end of message
  96. RESERR    EQU    30H        ;Reset error status
  97.  
  98.             ;STATUS BITS AND MASKS, RR 0
  99. ABORT    EQU    7        ;Break/abort
  100. MABORT    EQU    80H
  101. EOM    EQU    6        ;TX underrun/EOM
  102. MEOM    EQU    40H
  103. CTS    EQU    5        ;Clear-to-send line
  104. MCTS    EQU    20H
  105. DCD    EQU    3        ;Data-carrier-detect line
  106. MDCD    EQU    8
  107. TXBE    EQU    2        ;TX buffer empty
  108. MTXBE    EQU    4
  109. RXBF    EQU    0        ;RX buffer full
  110. MRXBF    EQU    1
  111.  
  112.             ;STATUS BITS AND MASKS, RR 1
  113. EOF    EQU    7        ;End of SDLC frame
  114. MEOF    EQU    80H
  115. FERR    EQU    6        ;Framing error
  116. MFERR    EQU    40H
  117. OVR    EQU    5        ;RX overrun
  118. MOVR    EQU    20H
  119. PERR    EQU    4        ;Parity error
  120. MPERR    EQU    10H
  121. MRES    EQU    0EH        ;Residue mask
  122. ALL    EQU    0        ;All sent
  123. MALL    EQU    1
  124.  
  125. RES8    EQU    0110B        ;Byte boundry residue
  126.  
  127.     ENTRY    HDLI,XSKED
  128.     ENTRY    CDS
  129.     ENTRY    I.TBE,I.RBF,I.EXT,I.SRX
  130.     EXT    SETTMR
  131.  
  132.     SUBTTL    'Callable Subroutines'
  133.     PAGE
  134. ;  HDLI - SIO initialization routine
  135.  
  136. HDLI:
  137.     LD    HL,SIOBI    ;SIO init data
  138.     LD    B,SIOBIL    ;Length of same
  139.     LD    C,(IY+CPORT)    ;SIO control port
  140.     OTIR            ;Init the SIO (rx mode)
  141.     XOR    A
  142.     LD    (IY+TSTA),A    ;Tx mode off (state 0)
  143.     LD    (IY+RSTA),A    ;Rx state 0 (hunt)
  144.     RET
  145.  
  146. ;  XSKED - Schedule transmission, either frame or CWID only
  147.  
  148. XSKED:
  149.     DI
  150.     LD    (IY+TSTA),1    ;Tx state = 1
  151.     LD    C,(IY+TXDLY)    ;Get TXDLY value
  152.     LD    B,(IY+(TXDLY+1))
  153.     LD    A,B        ;Check for no delay
  154.     OR    C        ;Well?
  155.     JR    Z,XSKED1    ;No delay, skip timer
  156.     PUSH    IY        ;Get structure base addr
  157.     POP    DE        ;Timer service argument
  158.     LD    HL,TSERVE    ;Where timer should call
  159.     LD    A,(IY+CHAN)    ;Get channel #
  160.     CALL    SETTMR        ;Set the timer
  161.     LD    (IY+TIMRUN),1    ;Show timer running
  162. XSKED1:    CALL    RTSON        ;Start modem up
  163.     EI
  164.     RET
  165.  
  166. ;  CDS - DCD line status reporting subroutine
  167.  
  168. CDS:
  169.     LD    C,(IY+CPORT)    ;SIO control port
  170.     IN    A,(C)        ;Get ext status
  171.     BIT    DCD,A        ;Test DCD line
  172.     LD    A,0        ;Assume off
  173.     RET    Z
  174.     LD    A,0FFH        ;Flag it on
  175.     RET
  176.     SUBTTL    'Tx Buffer Empty Interrupt Service'
  177.     PAGE
  178. ;  Transmitter buffer empty interrupt service.
  179. ;  Action is as follows:
  180. ;    State 0 (idle transmitter)
  181. ;        Spurious interrupt -- ignore it.
  182. ;    State 1 (waiting for CTS/timer)
  183. ;        Spurious interrupt -- ignore it.
  184. ;    State 2 (transmitting data)
  185. ;        Call NEXTHO for data byte.  If NEXTHO
  186. ;        returns data, send to SIO.  Otherwise,
  187. ;        stuff dummy data to SIO. If end of
  188. ;        transmission, state = 3, else 4.
  189. ;    State 3 (end of frame)
  190. ;        Call STFRM to re-start transmission.
  191. ;        State = 2
  192. ;    State 4 (first EOT fill byte)
  193. ;        Send dummy data to SIO, state = 5.
  194. ;    State 5 (second EOT fill byte)
  195. ;        Send dummy data to SIO, state = 6.
  196. ;    State 6 (end of transmission)
  197. ;        Set RTS off, call HODONE to flag
  198. ;        end of transmission, state = 0.
  199.  
  200. I.TBE:
  201.     LD    A,(IY+TSTA)    ;Get current state
  202.     INC    A
  203.     DEC    A        ;Idle state (0)?
  204.     JR    Z,SPURTI    ;Yes, ignore int.
  205.     DEC    A        ;Waiting state (1)?
  206.     JR    NZ,TXS2        ;No
  207. SPURTI:    LD    C,(IY+CPORT)    ;SIO Control port
  208.     LD    A,RESTXI    ;Reset tx interrupt
  209.     OUT    (C),A
  210.     RET
  211. TXS2:    DEC    A        ;Transmitting state (2)?
  212.     JR    NZ,TXS3        ;No
  213.     CALL    NEXTHO        ;Get next byte
  214.     OR    A        ;Is it a data byte?
  215.     JP    M,TXBYTE    ;Yes, send it
  216.     LD    C,(IY+CPORT)    ;SIO control port
  217.     LD    A,RESTXI    ;Reset the interrupt
  218.     OUT    (C),A
  219.     LD    (IY+TSTA),3    ;Assume end of frame
  220.     RET    Z        ;NEXTHO says end of frame
  221.     LD    (IY+TSTA),4    ;NEXTHO says end of transmission
  222.     RET
  223. TXBYTE:    LD    C,(IY+DPORT)    ;SIO data port
  224.     OUT    (C),B        ;Send data byte
  225.     RET
  226.     PAGE
  227. TXS3:    DEC    A        ;Fill 1 state (3)?
  228.     JR    NZ,TXS4        ;No
  229.     CALL    STFRM        ;Restart transmission
  230.     RET
  231. TXS4:    DEC    A        ;Fill 2 state (4)?
  232.     JR    NZ,TXS5        ;No
  233.     LD    (IY+TSTA),5    ;State = 5
  234.     LD    B,0        ;Data for fill
  235.     JR    TXBYTE        ;Send fill
  236. TXS5:    DEC    A        ;Fill 2 state (5)?
  237.     JR    NZ,TXTERM    ;No
  238.     LD    (IY+TSTA),6
  239.     LD    B,0
  240.     JR    TXBYTE
  241. TXTERM:    LD    (IY+TSTA),0    ;Show us stopped
  242.     CALL    RTSOFF        ;Stop transmitting
  243.     CALL    HODONE        ;Report finish
  244.     RET
  245.  
  246.     SUBTTL    'External/Status Interrupt Service'
  247.     PAGE
  248. ;  External/status interrupt handler.  Check to see if
  249. ;  rx frame aborted or DCD lost.  If so, kill rx frame
  250. ;  by setting rx state to 0. Then, if the tx state is 0,
  251. ;  return.  Otherwise, tx is active, so we will
  252. ;  check the TX underrun status.  If underrun and tx state
  253. ;  is 2, execute  tx state 8 routine (terminataion).
  254. ;  If no underrun error, vector through either the CTS true
  255. ;  or CTS false state table, as appropriate.
  256.  
  257. I.EXT:
  258.     LD    C,(IY+CPORT)    ;SIO control port
  259.     IN    A,(C)        ;Get status register
  260.     LD    B,RESEXT    ;Reset external status
  261.     OUT    (C),B
  262.     LD    B,A        ;Save status
  263.     AND    MABORT+MDCD    ;Mask all but abort, DCD
  264.     CP    MDCD        ;Status ok?
  265.     CALL    NZ,RXTERM    ;Terminate rx frame
  266.     LD    A,B        ;Get status back
  267.     LD    B,(IY+TSTA)    ;Get tx state
  268.     INC    B        ;Set to check
  269.     DEC    B        ;Tx state = 0?
  270.     RET    Z        ;Yes, nothing to do
  271.     PUSH    AF        ;Save status
  272.     BIT    EOM,A        ;Is underrun status?
  273.     JR    Z,I.XT10    ;No
  274.     LD    A,(IY+TSTA)    ;Get tx state
  275.     CP    2        ;State 2 (data xfer)?
  276.     JR    NZ,I.XT10    ;No
  277.     POP    AF        ;Clean stack
  278.     JP    TXTERM        ;Terminate xmsn
  279. I.XT10:    POP    AF        ;Get status into A
  280. CHKTX:    BIT    CTS,A        ;Is CTS on?
  281.     RET    Z        ;No, nothing to do
  282.     LD    A,(IY+TIMRUN)    ;Is timer running?
  283.     OR    A
  284.     RET    NZ        ;Yes, can't do anything
  285.     LD    A,(IY+TSTA)    ;Get tx state
  286.     CP    1        ;Waiting for it?
  287.     JR    Z,STFRM        ;Yes, start the frame
  288.     RET
  289.  
  290.     SUBTTL    'Internal Tx Subroutines'
  291.     PAGE
  292. ;  STFRM - Starts transmission of frame.
  293. ;  Call NEXTHO for data byte.  If none, ensure that RTS
  294. ;  is off and set tx state = 0.  Otherwise, reset Tx
  295. ;  CRC generator, send the data byte to the SIO and set
  296. ;  tx state = 2.
  297.  
  298. STFRM:
  299.     LD    C,(IY+CPORT)    ;SIO control port
  300.     LD    A,RESTCR    ;Reset TX CRC
  301.     OUT    (C),A
  302.     CALL    NEXTHO        ;Get that byte
  303.     LD    (IY+TSTA),2    ;State = 2
  304.     LD    C,(IY+DPORT)    ;SIO data port
  305.     OUT    (C),B        ;Send the data
  306.     LD    C,(IY+CPORT)    ;SIO control port
  307.     LD    A,RESEOM    ;Reset Tx EOM status
  308.     OUT    (C),A
  309.     RET
  310.  
  311. ;  RTSON - Turns RTS on
  312.  
  313. RTSON:
  314.     LD    C,(IY+CPORT)    ;SIO control port
  315.     LD    A,5        ;Select WR 5
  316.     OUT    (C),A
  317.     LD    A,0EBH        ;Set RTS true
  318.     OUT    (C),A
  319.     RET
  320.  
  321. ;  RTSOFF - Turn RTS off
  322.  
  323. RTSOFF:
  324.     LD    C,(IY+CPORT)    ;SIO control port
  325.     LD    A,5        ;Select WR 5
  326.     OUT    (C),A
  327.     LD    A,0E9H        ;Set RTS false
  328.     OUT    (C),A
  329.     RET
  330.  
  331. ;  TSERVE - Timer service
  332.  
  333. TSERVE:
  334.     PUSH    DE        ;Get data structure base
  335.     POP    IY
  336.     LD    (IY+TIMRUN),0    ;Show timer stopped
  337.     LD    C,(IY+CPORT)    ;SIO control register
  338.     IN    A,(C)        ;Get status
  339.     JP    CHKTX        ;Go check transmission
  340.  
  341.     SUBTTL    'Rx Buffer Full Interrupt Service'
  342.     PAGE
  343. ;  Receive buffer full interrupt routine.  Get received
  344. ;  char into B and exwcute based on receive state.
  345.  
  346. I.RBF:
  347.     LD    C,(IY+DPORT)    ;SIO data port
  348.     IN    B,(C)        ;Get received data byte
  349.     LD    A,(IY+RSTA)    ;Get rx state
  350.     INC    A
  351.     DEC    A        ;Is rx state 0?
  352.     JR    NZ,RS1        ;No
  353.  
  354. ;  Rx State 0, the idle state, is maintained until the first
  355. ;  receive interrupt.  Due to the fact that the SIO passes
  356. ;  FCS as data, a one byte buffer is used to insure that FCS
  357. ;  never gets passed to NEXTHI.
  358. ;  Store received char in buffer, state = 1
  359.  
  360.     LD    (IY+CBUF),B    ;Buffer received char
  361.     LD    (IY+RSTA),1    ;Next state = 1
  362.     RET
  363.  
  364. RS1:    DEC    A        ;Is rx state 1?
  365.     JR    NZ,RS2
  366.  
  367. ;  Rx states 1 and 2 - Place the received char in the
  368. ;  buffer, sending the current buffer char to NEXTHI.
  369. ;  Set state = 2
  370.  
  371.     LD    A,0        ;Flag SOM to NEXTHI
  372.     JR    GIVERX
  373.  
  374. RS2:    LD    A,0FFH        ;Flag next data byte to NEXTHI
  375.  
  376. GIVERX:    LD    C,(IY+CBUF)    ;Save buffer char
  377.     LD    (IY+CBUF),B    ;Buffer received char
  378.     LD    B,C        ;Get old buffer char
  379.     CALL    NEXTHI        ;Give to upper level sub
  380.     LD    (IY+RSTA),2    ;Next state = 2
  381.     RET
  382.  
  383.     PAGE
  384. ;  Special receive interrupt routine.  Occurs on error
  385. ;  or end of frame.  If in state 2 and no error,
  386. ;  execute state 3 routine (valid EOM).  If error status,
  387. ;  terminate frame.  Possible errors: CRC error, rx
  388. ;  underrun, invalid residue code (not 8-bit boundry)
  389.  
  390. I.SRX:
  391.     LD    C,(IY+CPORT)    ;SIO control port
  392.     LD    A,1        ;Set RR 1
  393.     OUT    (C),A
  394.     IN    A,(C)        ;Get special rx status
  395.     LD    B,A        ;Save it
  396.     LD    A,RESERR     ;Reset error status
  397.     OUT    (C),A
  398.     LD    C,(IY+DPORT)    ;SIO data port
  399.     IN    A,(C)        ;Get last FCS byte
  400.     LD    A,B        ;Get status
  401.     AND    MEOF+MFERR+MOVR+MRES
  402.                 ;Save the important bits
  403.     CP    MEOF+RES8    ;Proper end of frame?
  404.     JR    NZ,RXTERM    ;No, terminate frame
  405.     LD    A,(IY+RSTA)    ;We in state 2?
  406.     CP    2
  407.     LD    A,1        ;NEXTHI final flag
  408.     CALL    Z,NEXTHI    ;Tell NEXTHI is a good one
  409. RXTERM:    LD    (IY+RSTA),0    ;Reset to state 0
  410.     RET
  411.     PAGE
  412. ;  External subroutine calls
  413.  
  414. NEXTHO:
  415.     LD    L,(IY+NXTHO)    ;Get NXTHO address
  416.     LD    H,(IY+(NXTHO+1))
  417.     JP    (HL)
  418.  
  419. NEXTHI:
  420.     LD    L,(IY+NXTHI)    ;Get NXTHI address
  421.     LD    H,(IY+(NXTHI+1))
  422.     JP    (HL)
  423.  
  424. HODONE:
  425.     LD    L,(IY+ODONE)    ;Get ODONE address
  426.     LD    H,(IY+(ODONE+1))
  427.     JP    (HL)
  428.  
  429. ;  Fixed data
  430.  
  431. ;  SIO initialization block.
  432.  
  433. SIOBI:    DB    18H        ;Reset SIO
  434.     DB    4        ;WR 4
  435.     DB    00100000B     ;SDLC mode, x1 clock
  436.     DB    5        ;WR 5
  437.     DB    11101001B     ;DTR on, RTS off
  438.     DB    3        ;WR 3
  439.     DB    11111001B     ;8 bits, enables
  440.     DB    7        ;WR 7
  441.     DB    01111110B     ;SDLC flag byte
  442.     DB    1        ;WR 1
  443.     DB    00011111B     ;Enable rx, ext ints
  444. SIOBIL    EQU    $-SIOBI
  445.  
  446.     END
  447.