home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / forum3.lzh / EXAMPL / sc68681.a < prev    next >
Text File  |  1987-11-05  |  25KB  |  1,099 lines

  1.  ttl SC68681 DUART Device Driver
  2.  nam SC68681
  3.  
  4. *******************************************************************************
  5. * Edition History
  6. *
  7. * #  Date     Comments                                                   by
  8. * -- -------- --------------------------------------------------------- ----
  9. * 0  87/07/20  Initial Version from GMX SC68681 disassembled             mst
  10. * 1  87/10/01  Adapted to SCN68681-Hardware on mc68'000                  mst
  11. *
  12.  
  13. Edition equ 1
  14.  
  15. Typ_Lang equ (Drivr<<8)+Objct
  16. Attr_Rev equ (ReEnt<<8)+0
  17.  
  18.  psect SC68681,Typ_Lang,Attr_Rev,Edition,0,SC681ENT
  19.  
  20.  use <defsfile>
  21.  
  22. *********************************************
  23. * Device Driver Variables
  24. *
  25.  
  26.  vsect
  27. V_RBufWrt DS.L 1      writepointer to Readbuffer
  28. V_RBufRd DS.L 1       readpointer to Readbuffer
  29. V_RBufEnd DS.L 1      pointer to end of Readbuffer
  30. V_InCnt DS.W 1        number of chars in Inputbuffer
  31. V_WBufWrt DS.L 1      writepointer of Writebuffer
  32. V_WBufRd DS.L 1       readpointer to Writebuffer (next character)
  33. V_WBufEnd DS.L 1      pointer to end of Writebuffer
  34. V_OutCnt DS.W 1       number of chars in Outputbuffer
  35. V_BaseAd DS.L 1       baseaddress of SCN68681
  36. * V_IBase DS.B 1        offset to interrupt area in D_DuImr (always 0)
  37.  align
  38. V_Chanel DS.B 1       Flag: Channel A = 0, B = 1
  39. V_XOnFlg DS.B 1       XOn/XOff-Flag: Bit 7=1:XOn/XOff to send, Code in bit 0-7
  40. *                                    Bit 7=0:Nothing to send
  41. V_Flag DS.W 1         Bit 0: 0=XOn, 1=XOff; Bit 1: 0=new writechar, 1=no char
  42. V_ProcID DS.W 1       Store Caller's Process ID of Signal to be sent
  43. V_SigCod DS.W 1       Store Signal Code to be sent
  44. V_PathNr DS.W 1       Store Pathnumber (Only once used !?!)
  45.  
  46. V_SigBf1 DS.W 1       Requesters Process ID
  47.          DS.W 1       Signal Code
  48.          DS.B 1       Path Number
  49.  align
  50. V_SigBf2 DS.W 1       Requesters Process ID
  51.          DS.W 1       Signal Code
  52.          DS.B 1       Path Number
  53.  align
  54.  
  55. V_IRQMsk DS.W 1        IRQ-Mask for SCN68681
  56. V_IRQEn DS.B 1         IRQ Enable pattern Rx & Tx
  57. V_Mask DS.B 1          IRQ Mask, IRQ Sources allowed
  58. V_RTSLine DS.B 1       RTS-Line on OP0(A), OP1(B)
  59. V_DTRLine DS.B 1       DTR-Line on OP3(B), OP4(A)
  60.  
  61. V_RBuf DS.B 80          Readbuffer
  62. RBufEnd
  63. V_WBuf DS.B 140         Writebuffer
  64. WBufEnd
  65.  ends
  66.  
  67. *********************************************
  68. * SCN68681 Register Definitions
  69. *
  70. * Registers for both Channels are accessed via Chip-Baseaddress
  71. * Registers for each Channel are accessed via Port-Address
  72. *
  73.  
  74. * Write Registers:
  75.  
  76. CSR      equ $3   Clock Select Reg.
  77. CR       equ $5   Command Register
  78. THR      equ $7   TX Holding Register
  79. ACR      equ $9   Aux. Control Register
  80. IMR      equ $B   Interrupt Mask Register
  81. CTUR     equ $D   C/T Upper Register
  82. CTLR     equ $F   C/T Lower Register
  83.  
  84. * CSRB   equ $13  Clock Select Reg. B
  85. * CRB    equ $15  Command Register B
  86. * THRB   equ $17  TX Holding Register B
  87.  
  88. OPCR     equ $1B  Output Port Conf. Reg.
  89.  
  90. OPRSet   equ $1D  Set Output Port Bits Command
  91. OPRRes   equ $1F  Reset Output Port Bits Command
  92.  
  93. * Read/Write Registers
  94.  
  95. MR       equ $1   Mode Register, 1 & 2
  96. * MRB    equ $11  Mode Register B, 1 & 2
  97. IVR      equ $19  Interrupt Vector Register
  98.  
  99. * Read Registers:
  100.  
  101. SRAB     equ $3   Status Register A,B
  102. RHR      equ $7   RX Holding Register
  103. IPCR     equ $9   Input Port Change Reg.
  104. ISR      equ $B   Interrupt Status Reg.
  105. CTU      equ $D   Counter/Timer Upper
  106. CTL      equ $F   Counter/Timer Lower
  107. * SRB    equ $13  Status Register B
  108. * RHRB   equ $17  RX Holding Register B
  109. * Input  equ $1B  Input Port
  110. StartCnt equ $1D  Start Counter Command
  111. StopCnt  equ $1F  Stop Counter Command
  112.  
  113. *********************************************
  114. * SCN68681 Commands
  115. *
  116.  
  117. C_No     equ $0    No Command
  118. C_ResMR  equ $10   Reset MR Pointer
  119. C_ResRec equ $20   Reset Receiver
  120. C_ResTrs equ $30   Reset transmitter
  121. C_ResErr equ $40   Reset Error Status
  122. C_ResBrk equ $50   Reset break change IRQ
  123. C_StrBrk equ $60   Start break
  124. C_StpBrk equ $70   Stop break
  125.  
  126. *********************************************
  127. * SCN68681 Ststus Register Bit Definitions
  128. *
  129.  
  130. S_Break   equ 7    received break
  131. S_FramEr  equ 6    framing error
  132. S_Parity  equ 5    parity error
  133. S_Overun  equ 4    overrun error
  134. S_TxEMT   equ 3    Transmitter empty
  135. S_TxRDY   equ 2    Transmitter ready
  136. S_FFULL   equ 1    Read FIFO full
  137. S_RxRDY   equ 0    Receiver ready
  138.  
  139. E_FramEr  equ $40
  140. E_Parity  equ $20
  141. E_Overun  equ $10
  142.  
  143. *********************************************
  144. * SCN68681 Interrupt Mask- and Statusregister
  145. *
  146.  
  147. I_InpPrt  equ $80  Input Port Change
  148. I_CgBrkB  equ $40  Change in Break Channel B
  149. I_RxRDYB  equ $20  Receiver ready or FIFO full Channel B
  150. I_TxRDYB  equ $10  Transmitter Ready Channel B
  151. I_CntRdy  equ $08  Counter ready
  152. I_CgBrkA  equ $04  Change in Break Channel A
  153. I_RxRDYA  equ $02  Receiver ready of FIFO full Channel A
  154. I_TxRDYA  equ $01  Transmitter ready Channel A
  155.  
  156. *********************************************
  157. * SCN68681 Auxiliary Control Register
  158. *
  159.  
  160. A_IP3Int  equ $08  IP3 change of state IRQ-enable
  161. A_IP2Int  equ $04
  162. A_IP1Int  equ $02
  163. A_IP0Int  equ $01
  164.  
  165. *********************************************
  166. * Input/Output Port Bits Usage
  167. *
  168.  
  169. RTSxN     equ $80  Set MR to use OP(0),OP(1) as RTS
  170. CTSxN     equ $10  set MR to use IP(0),IP(1) as CTS
  171.  
  172. IP0       equ $01  Channel A CTS-Line
  173. IP1       equ $02  Channel B CTS-Line
  174. IP2       equ $03  Channel B DCD-Line
  175. IP3       equ $04
  176. IP4       equ $05
  177. IP5       equ $06
  178.  
  179. OP0       equ $01  Channel A RTS-Line
  180. OP1       equ $02  Channel B RTS-Line
  181. OP2       equ $04
  182. OP3       equ $08  Channel B DTR-Line
  183. OP4       equ $10  Channel A DTR-Line
  184. OP5       equ $20
  185. OP6       equ $40
  186. OP7       equ $80
  187.  
  188. *********************************************
  189. * Default Settings of sc68681-Parameters
  190. *
  191.  
  192. BrgClk    equ $E0  Baudrateset 2 & Clock on X1/CLK
  193.  
  194. *********************************************
  195. * Global Variables defined in 'IOGLOB.A'
  196. *
  197.  
  198. * D_DuImr  ds.b 2  IRQ-Mask for two SCN68681
  199.  
  200. *********************************************
  201. * Drivers Jumptable
  202. *
  203.  
  204. SC681ENT DC.W Init
  205.  DC.W Read
  206.  DC.W Write
  207.  DC.W GetStat
  208.  DC.W SetStat
  209.  DC.W Term
  210.  
  211. *********************************************
  212. * Initialize device and its static storage
  213. *
  214. * INPUT:  (a1)  device descriptor module
  215. *         (a2)  device static storage
  216. *         (a6)  system global data
  217. *
  218. * USAGE   (a3)  device portaddress
  219. *         (a5)  device portaddress with 4 LSB's zero
  220. *
  221. * OUTPUT  none
  222. *
  223. * ERROR   cc    Carry set
  224. *         d1.w  Error Code
  225. *
  226.  
  227. AdDec        equ        $FF7948
  228.  
  229. Init:        
  230.  move.w     M$DevCon(a1),d0
  231.  move.b     2(a1,d0.w),d0    Slotno. aus Dev-Descr
  232.  clr.l     d2
  233.  move.b     d0,d2
  234.  mulu     #16,d2            Offset berechnen
  235.  movea.l #SlotTab,a3    ptr auf Slottab
  236.  cmpi.l  #DUART_K,0(a3,d2.w) already initialized ?
  237.  beq.s   InitPORT
  238.  addi.b     #$f8,d0        f. AdrDecod. aufbereiten
  239.  move.l     ROMBOT,a0        ROMBOT holen
  240.  jsr     AdDec            Slot programmieren
  241.  move.l     #DUART_K,0(a3,d2.w) Kennung in Slottab
  242.  move.l     a0,4(a3,d2.w)    Addresse in Slottab.
  243.  suba.l     #$4000,a0        ROMBOT korrigieren
  244.  move.l     a0,ROMBOT
  245.  
  246. InitPORT: move.l 4(a3,d2.w),d0
  247.  add.l d0,V_PORT(a2)     add cardadr and channeladr
  248.  
  249.  MOVEA.L V_PORT(A2),A3 get device portaddress
  250.  MOVE.L A3,D0
  251.  BTST #3,D0 test which channel
  252.  BNE.S InitB
  253.  
  254.  CLR.B V_Chanel(A2) Init Channel A
  255.  MOVE.B #OP0,V_RTSLine(A2) prepare so set OP0 to Low
  256.  MOVE.B #OP4,V_DTRLine(A2)
  257.  MOVE.B #I_RxRDYA+I_TxRDYA,V_IRQEn(A2) Enable Rx & Tx IRQ's
  258.  MOVE.B #$FE,V_Mask(A2) Tx IRQ not allowd
  259.  BRA.S Init01
  260.  
  261. InitB: MOVE.B #1,V_Chanel(A2) Init Channel B
  262.  MOVE.B #OP1,V_RTSLine(A2) prepare to set OP1 to Low
  263.  MOVE.B #OP3,V_DTRLine(A2)
  264.  MOVE.B #I_RxRDYB+I_TxRDYB,V_IRQEn(A2) Enable Rx & Tx IRQ's
  265.  MOVE.B #$EF,V_Mask(A2) Tx IRQ not allowed
  266.  
  267. Init01: ANDI.B #$F0,D0 get baseaddress of port
  268.  MOVEA.L D0,A5
  269.  MOVE.L D0,V_BaseAd(A2)
  270.  
  271. * Setup IRQ-Mask
  272.  
  273.  MOVE.B M$IRQLvl(A1),D2 get hardware IRQ Level
  274.  ASL.W #8,D2 shift into priority
  275.  BSET #13,D2 set systemstate bit
  276.  MOVE.W D2,V_IRQMsk(A2)
  277.  
  278. * Initialize SCN68681 Hardware
  279.  
  280.  MOVE SR,-(A7)
  281.  MOVE D2,SR
  282.  BSR InitDev Initialize SCN68681
  283.  MOVE (A7)+,SR
  284.  TST.B D1
  285.  BNE InitErr
  286.  
  287. * Initialize Bufferpointers and Flags
  288.  
  289.  BSET #1,V_Flag(A2) no char in writebuffer
  290.  LEA V_RBuf(A2),A0
  291.  MOVE.L A0,V_RBufWrt(A2)
  292.  MOVE.L A0,V_RBufRd(A2)
  293.  LEA RBufEnd-V_RBuf(A0),A0 end of readbuffer
  294.  MOVE.L A0,V_RBufEnd(A2)
  295.  LEA V_WBuf(A2),A0
  296.  MOVE.L A0,V_WBufWrt(A2)
  297.  MOVE.L A0,V_WBufRd(A2)
  298.  LEA WBufEnd-V_WBuf(A0),A0
  299.  MOVE.L A0,V_WBufEnd(A2)
  300.  
  301. * Setup IRQ-Handler and D_DuImr
  302.  
  303.  MOVE.B M$Vector(A1),D0
  304.  MOVE.B M$Prior(A1),D1
  305.  LEA IRQEnt(PC),A0
  306.  OS9 F$IRQ
  307.  BCS.S InitRts
  308.  MOVEA.L V_PORT(A2),A3
  309.  move.b M$Vector(a1),IVR(a3) set up Interrupt vector
  310.  MOVE SR,-(A7)
  311.  MOVE V_IRQMsk(A2),SR
  312.  MOVE.B #$05,CR(A3) enable Tx and Rx
  313.  LEA D_DuImr(A6),A4 interrupt mask register base
  314. * ADDA.W V_IBase(A2),A4 always 0
  315.  MOVE.B V_IRQEn(A2),D3
  316.  OR.B D3,(A4) two channels/one byte
  317.  MOVE.B V_Mask(A2),D3
  318.  AND.B D3,(A4)
  319.  MOVEA.L V_BaseAd(A2),A5
  320.  MOVE.B (A4),IMR(A5)
  321.  MOVE (A7)+,SR
  322.  MOVE.B V_RTSLine(A2),OPRSet(A5)
  323.  MOVEQ #0,D1
  324. InitRts: RTS
  325.  
  326. *********************************************
  327. * Initialize Device
  328. * Resets Port A/B depending on (a3)
  329. *
  330. * INPUT   (a3)   port address (A or B)
  331. *         (a5)   device baseaddr
  332. *
  333.  
  334. InitDev: MOVE.B #C_ResRec,CR(A3) Reset Channel Receiver
  335.  NOP
  336.  MOVE.B #C_ResTrs,CR(A3) Reset Channel Transmitter
  337.  NOP
  338.  MOVE.B #C_ResErr,CR(A3) Reset Error Status
  339.  NOP
  340.  MOVE.B #C_ResBrk,CR(A3) Reset break change IRQ
  341.  NOP
  342.  MOVE.B #BrgClk,ACR(A5) Baudrateset and Clocksource
  343.  NOP
  344.  MOVE.B #$00,CTUR(A5) Set Timer
  345.  NOP
  346.  MOVE.B #$03,CTLR(A5)
  347.  
  348. *********************************************
  349. * Select Baudrate
  350. *
  351.  
  352. * Set Clock Select Register CSR
  353.  
  354.  move.b $5D(a1),d0
  355. * MOVE.B PD_BAU(A1),D0 Adjustable Baud Rate
  356.  CMPI.B #$FF,D0 External not allowed
  357.  BEQ.S InitErr
  358.  ANDI.W #$001F,D0
  359.  CMP.B #$10,D0 19'000 Baud
  360.  BHI.S InitErr
  361.  MOVE.B BaudTab(PC,D0.W),D0
  362.  CMP.B #$FF,D0 not allowed with Set choosen
  363.  BEQ.S InitErr
  364.  MOVE.B D0,CSR(A3) Clock Select
  365.  
  366. * set Mode Register 1
  367.  
  368.  move.b $5C(a1),d0
  369. * MOVE.B PD_PAR(A1),D0 Parity Code
  370.  MOVE.B D0,D2
  371.  MOVE.B #C_ResMR,CR(A3) Reset MR Pointer
  372.  ANDI.W #3,D0 mask parity
  373.  MOVE.B ParTab(PC,D0.W),D0
  374.  BMI.S InitErr
  375.  MOVE.B D2,D1
  376.  ANDI.W #$C,D1 mask number of bits/char
  377.  ASR.W #2,D1
  378.  OR.B BitsTab(PC,D1.W),D0
  379.  ORI.B #RTSxN,D0 control by RxRTS Signal
  380.  MOVE.B D0,MR(A3) Set Mode Register 1
  381.  
  382. * set Mode Register 2
  383.  
  384.  MOVE.B D2,D1
  385.  ANDI.W #$30,D1 mask number of stop bits
  386.  ASR.W #4,D1
  387.  MOVE.B StopTab(PC,D1.W),D0
  388.  BMI.S InitErr
  389.  ANDI.B #$0C,D2 mask number of bits/char
  390.  CMP.B #$0C,D2 5 Bits/char
  391.  BEQ.S InitDev1
  392.  CMPI.B #$01,D1 1 1/2 stop bits
  393.  BNE.S InitDev1
  394.  ADDQ.B #1,D0 add 0.5 to stop bit length for 5 bits/char
  395. InitDev1: ORI.B #CTSxN,D0 CTS enable
  396.  MOVE.B D0,MR(A3) Set Mode Register 2
  397.  CLR.W D1
  398.  RTS
  399.  
  400. InitErr: MOVE.W #E$BMode,D1 Error, bad I/O Mode
  401.  ORI #Carry,ccr
  402.  RTS
  403.  
  404. *********************************************
  405. * Initializationtable for SCN68681
  406. *
  407.  
  408. BaudTab: DC.B $FF,$00,$11,$22,$33,$44,$55,$66,$AA
  409.          DC.B $77,$88,$FF,$99,$FF,$BB,$CC,$DD
  410. ParTab:  DC.B $10,$04,$FF,$00
  411. BitsTab: DC.B $03,$02,$01,$00
  412. StopTab: DC.B $07,$07,$0F,$FF
  413.          DC.B $00
  414.  
  415. *********************************************
  416. * Get next character
  417. *
  418. * INPUT   (a1)  path descriptor
  419. *         (a2)  device static storage
  420. *         (a4)  process descriptor
  421. *         (a6)  system global data
  422. *
  423. * OUTPUT  d0.b  input character
  424. *
  425. * ERROR   cc    Carry set
  426. *         d1.w  Error Code
  427. *
  428.  
  429. Read00: MOVE.W V_BUSY(A2),V_WAKE(A2)
  430.  MOVE (A7)+,SR
  431.  BSR Sleep
  432.  
  433. Read: TST.B V_XOnFlg(A2) XOn/XOff to send ?
  434.  BLE.S ReadChar
  435.  
  436. * if XOn/XOff to send or if XOff sent by RxIRQ (bit7=0)
  437.  
  438.  CMPI.W #10,V_InCnt(A2)
  439.  BHI.S ReadChar
  440.  
  441. * less than 10 char in buffer and RxIRQ sent XOff --> send XOn
  442.  
  443.  MOVE.B V_XON(A2),D1
  444.  MOVEA.L V_PORT(A2),A3
  445.  MOVE SR,-(A7)
  446.  MOVE V_IRQMsk(A2),SR
  447.  BTST #S_TxRDY,SRAB(A3) Transmitter Ready ?
  448.  BEQ.S RTrNRdy no-->
  449.  CLR.B V_XOnFlg(A2) XOn/XOff sent
  450.  MOVE.B D1,THR(A3) TX Holding Register
  451.  BRA.S Read01
  452.  
  453. * mark XOn to be sent if transmitter goes ready
  454.  
  455. RTrNRdy: ORI.B #$80,D1 set XOn/XOff to send bit
  456.  MOVE.B D1,V_XOnFlg(A2)
  457.  MOVEA.L V_BaseAd(A2),A0
  458.  MOVE.B V_IRQEn(A2),D3
  459. *@ LEA D_DuImr(A6),A5
  460. * ADDA.W V_IBase(A2),A5
  461. *@ OR.B D3,(A5)
  462. *@ MOVE.B (A5),IMR(A0) Interrupt Mask Register
  463.  
  464. Read01: MOVE (A7)+,SR
  465.  
  466. *********************************************
  467. * Read character from readbuffer
  468. *
  469.  
  470. ReadChar: TST.W V_ProcID(A2) ID of signal to be sent
  471.  BNE.S NotRdyErr
  472.  MOVE SR,-(A7)
  473.  MOVE V_IRQMsk(A2),SR
  474.  TST.W V_InCnt(A2)
  475.  BEQ.S Read00
  476.  MOVE (A7)+,SR
  477.  MOVEA.L V_RBufRd(A2),A0
  478.  MOVE.B (A0)+,D0
  479.  SUBQ.W #1,V_InCnt(A2)
  480.  CMPA.L V_RBufEnd(A2),A0
  481.  BCC.S RdChar00
  482.  LEA V_RBuf(A2),A0
  483. RdChar00: MOVE.L A0,V_RBufRd(A2)
  484.  MOVE.B V_ERR(A2),PD_ERR(A1)
  485.  BEQ.S ReadEnd no error
  486.  
  487.  CLR.B V_ERR(A2)
  488.  MOVE.W #E$Read,D1
  489.  BRA.S Err
  490.  
  491. NotRdyErr: MOVE.W #E$NotRdy,D1
  492. Err ORI #Carry,ccr
  493.  
  494. ReadEnd: RTS
  495.  
  496. *********************************************
  497. * Sleep until awakened by IRQ
  498. *
  499.  
  500. Sleep: MOVEM.L D0/A0,-(A7)
  501.  MOVEQ #0,D0 sleep until awakened by signal
  502.  OS9 F$Sleep
  503.  MOVE.W P$Signal(A4),D1 get signal sent
  504.  BNE.S SigKind
  505. State: BTST #Condemn,P$State(A4) process died ?
  506.  BNE.S SigErr
  507.  MOVEM.L (A7)+,D0/A0
  508.  RTS
  509.  
  510. SigKind: CMPI.W #S$Intrpt,D1 non user signals 0-3
  511.  BHI.S State
  512. SigErr: LEA $C(A7),A7
  513.  BRA.S Err
  514.  
  515. *********************************************
  516. * Output a character
  517. *
  518. * INPUT   d0.b  char to write
  519. *         (a1)  path descriptor
  520. *         (a2)  device static storage
  521. *         (a4)  process descriptor pointer
  522. *         (a6)  system global data
  523. *
  524. * OUTPUT  none
  525. *
  526. * ERROR   cc    Carry set
  527. *         d1.w  Error Code
  528. *
  529.  
  530. Write00: MOVE.W V_BUSY(A2),V_WAKE(A2)
  531.  MOVE (A7)+,SR
  532.  BSR.S Sleep
  533.  
  534. Write: MOVE SR,-(A7)
  535.  MOVE V_IRQMsk(A2),SR
  536.  MOVE.W V_OutCnt(A2),D2
  537.  CMPI.W #WBufEnd-V_WBuf,D2
  538.  BCC.S Write00
  539.  ADDQ.W #1,V_OutCnt(A2)
  540.  MOVEA.L V_WBufWrt(A2),A0
  541.  MOVE.B D0,(A0)+ store char in writebuffer
  542.  CMPA.L V_WBufEnd(A2),A0
  543.  BCC.S Write1
  544.  LEA V_WBuf(A2),A0 reset bufferpointer
  545.  
  546. Write1: MOVE.L A0,V_WBufWrt(A2) update pointer
  547.  BCLR #1,V_Flag(A2) set Flag: new char in buffer
  548.  MOVEA.L V_BaseAd(A2),A0
  549.  MOVE.B V_IRQEn(A2),D3
  550. *@ LEA D_DuImr(A6),A5
  551. * ADDA.W V_IBase(A2),A5
  552. *@ OR.B D3,(A5)
  553. *@ MOVE.B (A5),IMR(A0)
  554.  MOVE (A7)+,SR
  555.  CLR.L D1
  556.  RTS
  557.  
  558. *********************************************
  559. * GETSTAT/SETSTAT device status
  560. *
  561. * INPUT  d0.w  function code
  562. *        (a1)  path descriptor
  563. *        (a2)  device static storage
  564. *        (a6)  system global data
  565. *
  566. * OUTPUT  depends upon function code
  567. *
  568. * ERROR   cc    Carry set
  569. *         d1.w  Error Code
  570. *
  571.  
  572. GetStat: CMPI.W #SS_Ready,D0
  573.  BNE.S GStat00
  574.  
  575. *********************************************
  576. * Test for data available
  577. *
  578. * INPUT  none
  579. *
  580. * OUTPUT d1.l Nr of input chars available
  581. *
  582.  
  583.  MOVEA.L PD_RGS(A1),A0 SS_Ready returns number of chars available
  584.  CLR.W R$d1(A0)
  585.  MOVE.W V_InCnt(A2),R$d1+2(A0)
  586.  BEQ NotRdyErr no char available
  587.  RTS
  588.  
  589. GStat00: CMPI.W #SS_EOF,D0 test for EOF
  590.  BEQ.S GStatEnd
  591.  
  592. StatErr: MOVE.W #E$UnkSvc,D1
  593.  ORI #Carry,ccr
  594. GStatEnd: RTS
  595.  
  596. *********************************************
  597. * SETSTAT Device Status
  598. *
  599. * USAGE  (a5)  addr to D_DuImr+Offset
  600. *
  601.  
  602. SetStat: MOVEA.L V_BaseAd(A2),A0
  603. *@ LEA D_DuImr(A6),A5
  604. * ADDA.W V_IBase(A2),A5
  605.  CMPI.W #SS_SSig,D0
  606.  BNE.S SetStat1
  607.  
  608. *********************************************
  609. * Send Signal on data ready
  610. *
  611. * INPUT  d2.w  user defined signal code
  612. * OUTPUT none
  613. *
  614.  
  615.  TST.W V_ProcID(A2)
  616.  BNE NotRdyErr
  617.  MOVE.W PD_CPR(A1),D0 Requesters Process ID
  618.  MOVEA.L PD_RGS(A1),A4 Addr of caller's MPU Register Stack
  619.  MOVE.W R$d2+2(A4),D1 get signal code
  620.  MOVE SR,-(A7)
  621.  MOVE V_IRQMsk(A2),SR
  622.  TST.W V_InCnt(A2)
  623.  BNE.S Rel00 data ready --> go to send signal
  624.  
  625. * prepare Signal to be sent if char arrives
  626.  
  627.  MOVE.W D0,V_ProcID(A2)
  628.  MOVE.W D1,V_SigCod(A2)
  629.  MOVE.W PD_PD(A1),V_PathNr(A2) nowhere else used !?!
  630.  MOVE.B V_IRQEn(A2),D3
  631. *@ OR.B D3,(A5)
  632. *@ MOVE.B (A5),IMR(A0) IRQ Mask Register
  633.  
  634. SSig01: MOVE (A7)+,SR
  635. SSig02: CLR.W D1
  636.  RTS
  637.  
  638. SetStat1: CMPI.W #SS_Relea,D0 Release Device
  639.  BNE.S SetStat2
  640.  
  641. *********************************************
  642. * Release device
  643. *
  644. * INPUT  none
  645. * OUTPUT none
  646. *
  647.  
  648.  MOVE.W PD_CPR(A1),D2 Requesters Process ID
  649.  LEA V_ProcID(A2),A3
  650.  BSR.S PrcIdTst test for correct proc. ID and path Nr.
  651.  TST.B V_Chanel(A2)
  652.  BEQ.S SSig02 Chanel A: return, no error
  653.  LEA V_SigBf2(A2),A3
  654.  BSR.S PrcIdTst
  655.  LEA V_SigBf1(A2),A3
  656.  BSR.S PrcIdTst
  657.  TST.W V_SigBf2(A2)
  658.  BNE.S SSig02
  659.  TST.W V_SigBf1(A2)
  660.  BNE.S SSig02
  661.  MOVE.B #BrgClk,ACR(A0) baudrateset and clocksource
  662.  MOVE SR,-(A7)
  663.  MOVE V_IRQMsk(A2),SR
  664. *@ BCLR #7,(A5)
  665. *@ BEQ.S SSig01
  666. *@ MOVE.B (A5),IMR(A0)
  667.  BRA.S SSig01
  668.  
  669. Rel00: MOVE (A7)+,SR
  670.  BRA SendSig
  671.  
  672. *********************************************
  673. * Test if current Process ID and Path Number matches
  674. * values stored in SigBfx
  675. *
  676. * INPUT  (a3)  address of SigBfx
  677. *        d2.w  current process ID
  678. *
  679. * OUTPUT Signal sent on match and SigBfx cleared,
  680. *        otherwhise nothing
  681. *
  682.  
  683. PrcIdTst: CMP.W (A3),D2 test process ID
  684.  BNE.S PrcTst00
  685.  MOVE.W PD_PD(A1),D0 Path number
  686.  CMP.W $4(A3),D0 test Path Number
  687.  BNE.S PrcTst00
  688.  CLR.W (A3) clear process ID in SigBfx
  689. PrcTst00: RTS
  690.  
  691. *
  692.  
  693. SetStat2: TST.B V_Chanel(A2)
  694.  BEQ.S SetStat4
  695.  CMPI.W #SS_DCOn,D0
  696.  BNE.S SetStat3
  697.  
  698. *********************************************
  699. * Sends Signal when Data Carrier Detect line goes true
  700. * (only Channel B)
  701. *
  702. * INPUT  d2.w  Signal Code to be sent
  703. * OUTPUT none
  704. *
  705.  
  706.  LEA V_SigBf1(A2),A3
  707.  BRA.S Signal
  708.  
  709. SetStat3: CMPI.W #SS_DCOff,D0
  710.  BNE.S SetStat4
  711.  
  712. *********************************************
  713. * Sends Signal when data detect carrier line goes false
  714. * (only Channel B)
  715. *
  716. * INPUT  d2.w  Signal Code to be sent
  717. * OUTPUT none
  718. *
  719.  
  720.  LEA V_SigBf2(A2),A3
  721.  
  722. Signal: MOVE.W PD_CPR(A1),(A3) Requesters process ID
  723.  MOVEA.L PD_RGS(A1),A4
  724.  MOVE.W R$d2+2(A4),2(A3) store Signal Code to SigBf2
  725.  MOVE.B PD_PD(A1),4(A3) store Path Number
  726.  MOVE.B #BrgClk+A_IP2Int,ACR(A0) enable IP2 change of state IRQ
  727.  MOVE SR,-(A7)
  728.  MOVE V_IRQMsk(A2),SR
  729. *@ ORI.B #I_InpPrt,(A5) Inputport-change IRQ-Enable in IMR
  730. * BSET #7,(A5) inputport-change IRQ enable in IMR
  731. *@ BNE SSig01
  732.  TST.B IPCR(A0)
  733. *@ MOVE.B (A5),IMR(A0)
  734.  BRA SSig01
  735.  
  736. SetStat4: CMPI.W #SS_EnRTS,D0
  737.  BNE.S SetStat5
  738.  
  739. *********************************************
  740. * Enable RTS line (DTR-Line)
  741. *
  742. * INPUT  none
  743. * OUTPUT none
  744. *
  745.  
  746.  LEA OPRSet(A0),A0 set Output Port Bits
  747.  BRA.S SetOutput
  748.  
  749. SetStat5: CMPI.W #SS_DsRTS,D0
  750.  BNE.S SetStat6
  751.  
  752. *********************************************
  753. * Disable RTS line (DTR-Line)
  754. *
  755. * INPUT  none
  756. * OUTPUT none
  757. *
  758.  
  759.  LEA OPRRes(A0),A0 reset Output Port Bits
  760. SetOutput: MOVE.B V_DTRLine(A2),(A0)
  761.  BRA.S StatEnd
  762.  
  763. SetStat6: CMPI.W #SS_Break,D0
  764.  BNE StatErr
  765.  
  766. *********************************************
  767. * Send Break
  768. *
  769. * INPUT  none
  770. * OUTPUT none
  771. *
  772.  
  773.  MOVEA.L V_PORT(A2),A3
  774.  MOVE.B #C_StrBrk,CR(A3)
  775.  MOVEQ #30,D0
  776.  OS9 F$Sleep
  777.  MOVE.B #C_StpBrk,CR(A3)
  778. StatEnd: CLR.B D1
  779.  RTS
  780.  
  781. *********************************************
  782. * Terminate device
  783. *
  784. * INPUT  (a1)  device descriptor pointer
  785. *        (a2)  device static storage
  786. *        (a6)  system global data
  787. *
  788. * OUTPUT none
  789. *
  790. * ERROR  cc    Carry set
  791. *        d1.w  Error Code
  792. *
  793.  
  794. Term00: MOVE.W V_BUSY(A2),V_WAKE(A2)
  795.  MOVE (A7)+,SR
  796.  PEA Term(PC)
  797.  BSR Sleep
  798.  ADDQ.L #4,A7
  799.  
  800. Term: MOVE.W P$ID(A4),V_BUSY(A2)
  801.  MOVE.W P$ID(A4),V_LPRC(A2)
  802.  MOVE SR,-(A7)
  803.  MOVE V_IRQMsk(A2),SR
  804.  TST.W V_OutCnt(A2)
  805.  BNE.S Term00 not all char sent
  806.  
  807.  MOVEQ #50,D0
  808.  OS9 F$Sleep
  809.  MOVE.B V_IRQEn(A2),D0
  810.  NOT.B D0
  811.  MOVEA.L V_BaseAd(A2),A0
  812. *@ LEA D_DuImr(A6),A5
  813. * ADDA.W V_IBase(A2),A5
  814. *@ AND.B D0,(A5)
  815. *@ MOVE.B (A5),IMR(A0) disable all IRQ's for that channel
  816.  MOVE (A7)+,SR
  817.  MOVEA.L V_PORT(A2),A3
  818.  MOVE.B #$0A,CR(A3) disable Tx, Rx
  819.  MOVE.B V_RTSLine(A2),D0
  820.  OR.B V_DTRLine(A2),D0
  821.  MOVE.B D0,OPRRes(A0)
  822.  MOVE.B M$Vector(A1),D0
  823.  SUBA.L A0,A0
  824.  OS9 F$IRQ
  825.  RTS
  826.  
  827. *********************************************
  828. * IRQ Service Routine
  829. *
  830. * INPUT   (a2)  static storage
  831. *         (a3)  port address
  832. *         (a6)  system global data
  833. *
  834. * USAGE    d0   IRQ Status Register
  835. *         (a0)  Baseaddress
  836. *
  837.  
  838. IRQEnt: MOVEA.L V_BaseAd(A2),A0
  839.  MOVE.B ISR(A0),D0 get IRQ-Status
  840.  LEA D_DuImr(A6),A3
  841. * ADDA.W V_IBase(A2),A3
  842.  AND.B (A3),D0
  843.  BNE.S IRQSvc
  844. IRQErr: ORI #Carry,ccr
  845.  RTS
  846.  
  847. IRQSvc: TST.B V_Chanel(A2)
  848.  BEQ.S ChA_IRQ
  849.  
  850. * Channel B IRQ servicing
  851.  
  852.  ANDI.B #$B0,D0 mask Input Port Change, RxRDY, TxRDY
  853.  BEQ.S IRQErr
  854.  MOVEA.L V_PORT(A2),A3
  855.  BTST #5,D0 RxRDY ?
  856.  BNE.S RxIRQ yes -->
  857.  BTST #7,D0 Input Port Change ?
  858.  BEQ TxIRQ no -->
  859.  
  860. * IRQ caused by Input Port Change
  861.  
  862.  MOVE.B IPCR(A0),D1
  863.  BTST #6,D1 Delta IP2 ?
  864.  BEQ.S IRQRet
  865.  BTST #2,D1 IP2 ?
  866.  BNE.S IP2On
  867.  TST.W V_SigBf1(A2) any process waiting on signal ?
  868.  BEQ.S IRQRet no -->
  869.  
  870.  MOVEM.W V_SigBf1(A2),D0-D1 send signal to waiting process
  871.  BSR SendSig
  872.  CLR.W V_SigBf1(A2)
  873.  
  874.  TST.W V_SigBf2(A2) any process waiting on signal ?
  875.  BNE.S IRQRet
  876.  BRA.S DisIP2
  877.  
  878. IP2On: TST.W V_SigBf2(A2)
  879.  BEQ.S IRQRet
  880.  MOVEM.W V_SigBf2(A2),D0-D1
  881.  BSR SendSig
  882.  CLR.W V_SigBf2(A2)
  883.  TST.W V_SigBf1(A2)
  884.  BNE.S IRQRet
  885.  
  886. DisIP2: MOVE.L A5,-(A7)
  887.  MOVE.B #BrgClk,ACR(A0) disable IP2 IRQ
  888. *@ LEA D_DuImr(A6),A5
  889. * ADDA.W V_IBase(A2),A5
  890. *@ BCLR #7,(A5)
  891. *@ MOVE.B (A5),IMR(A0)
  892.  MOVEA.L (A7)+,A5
  893. IRQRet: RTS
  894.  
  895. * Channel A IRQ servicing
  896.  
  897. ChA_IRQ: ANDI.B #$03,D0 mask TxRDY, RxRDY
  898.  BEQ IRQErr
  899.  MOVEA.L V_PORT(A2),A3
  900.  BTST #1,D0 RxRDY ?
  901.  BEQ.S TxIRQ no -->
  902.  
  903. * Receiver Rx Interrupt
  904.  
  905. RxIRQ: MOVE.B V_XOnFlg(A2),D1 XOn/XOff to send ?
  906.  BPL GetChar
  907.  BTST #S_TxRDY,SRAB(A3)
  908.  BEQ GetChar no -->
  909.  BCLR #7,D1 mask out XOn/XOff Code
  910.  MOVE.B D1,THR(A3) send XOn/XOff
  911.  MOVE.B V_XON(A2),D0
  912.  EOR.B D0,D1 d1=0 if XON sent
  913.  MOVE.B D1,V_XOnFlg(A2) d1<>0 (bit7=0) if XOff sent
  914.  BRA GetChar
  915.  
  916. * Transmitter Tx Interrupt
  917.  
  918. TxIRQ: MOVE.B V_XOnFlg(A2),D0
  919.  BPL.S SendDat
  920.  BCLR #7,D0
  921.  MOVE.B D0,THR(A3) send XOn/XOff
  922.  MOVE.B V_XON(A2),D1
  923.  EOR.B D1,D0
  924.  MOVE.B D0,V_XOnFlg(A2) mark if it was XOff
  925.  TST.B V_Flag(A2)
  926.  BNE.S SigIRQ no more data in buffer -> wakeup process
  927.  RTS
  928.  
  929. SendDat: MOVE.W V_OutCnt(A2),D0
  930.  BEQ.S TxEnd buffer empty -->
  931.  TST.B V_Flag(A2)
  932.  BNE.S SigIRQ no more data in buffer -> wakeup process
  933.  SUBQ.W #1,D0
  934.  MOVE.L A1,-(A7)
  935.  MOVEA.L V_WBufRd(A2),A1
  936.  MOVE.B (A1)+,THR(A3) send data
  937.  CMPA.L V_WBufEnd(A2),A1
  938.  BCS.S TxNorm00
  939.  LEA V_WBuf(A2),A1 reset buffer pointer
  940. TxNorm00: MOVE.L A1,V_WBufRd(A2)
  941.  MOVEA.L (A7)+,A1
  942.  MOVE.W D0,V_OutCnt(A2)
  943.  CMPI.W #10,D0
  944.  BHI.S SdSigEnd --> return
  945.  TST.W D0
  946.  BNE.S WakeUp
  947.  
  948. TxEnd: BSET #1,V_Flag(A2) no char available
  949.  
  950. * Wakeup process gone to sleep due to writebuffer full
  951.  
  952. SigIRQ: MOVE.B V_Mask(A2),D0
  953.  MOVE.L A5,-(A7)
  954. *@ LEA D_DuImr(A6),A5
  955. * ADDA.W V_IBase(A2),A5
  956. *@ AND.B D0,(A5)
  957. *@ MOVE.B (A5),IMR(A0)
  958.  MOVEA.L (A7)+,A5
  959.  
  960. WakeUp: MOVEQ #S$Wake,D1
  961.  MOVE.W V_WAKE(A2),D0
  962.  
  963. SendS00: BEQ.S SdSigEnd no process waiting
  964.  CLR.W V_WAKE(A2)
  965.  
  966. *********************************************
  967. * Subroutine to send a signal
  968. *
  969.  
  970. SendSig: MOVEA.L D_SysDis(A6),A0
  971.  OS9call F$Send,A0
  972.  CLR.W D1
  973. SdSigEnd: RTS
  974.  
  975. *********************************************
  976. * test error condition and get char read
  977. *
  978.  
  979. GetChar: MOVE.B SRAB(A3),D1
  980.  ANDI.B #E_FramEr+E_Parity+E_Overun,D1 mask errors
  981.  BEQ.S CtrlSeq no error -->
  982.  OR.B D1,V_ERR(A2)
  983.  MOVE.B #C_ResTrs,CR(A3)
  984.  NOP
  985.  
  986. * test for Controlsequences handled by the IRQ Server
  987.  
  988. CtrlSeq: MOVE.B RHR(A3),D0 get character
  989.  BEQ.S InsertCH
  990.  CMP.B V_INTR(A2),D0
  991.  BEQ CtrlC
  992.  CMP.B V_QUIT(A2),D0
  993.  BEQ CtrlE
  994.  CMP.B V_PCHR(A2),D0
  995.  BEQ Pause
  996.  CMP.B V_XON(A2),D0
  997.  BEQ XOn
  998.  CMP.B V_XOFF(A2),D0
  999.  BEQ XOff
  1000.  
  1001. *********************************************
  1002. * Insert Character in buffer
  1003. *
  1004.  
  1005. InsertCH: MOVE.L A1,-(A7)
  1006.  MOVEA.L V_RBufWrt(A2),A1
  1007.  MOVE.B D0,(A1)+ store char into buffer
  1008.  ADDQ.W #1,V_InCnt(A2)
  1009.  CMPI.W #RBufEnd-V_RBuf,V_InCnt(A2)
  1010.  BLS.S BfNtFull
  1011.  
  1012. * Readbuffer full
  1013.  
  1014.  SUBQ.W #1,V_InCnt(A2) Buffer full
  1015.  MOVEA.L (A7)+,A1
  1016.  BSET #4,V_ERR(A2)
  1017.  BRA WakeUp
  1018.  
  1019. * Insert char in readbuffer
  1020.  
  1021. BfNtFull: CMPA.L V_RBufEnd(A2),A1
  1022.  BCS.S Ins00
  1023.  LEA V_RBuf(A2),A1 reset buffer pointer
  1024. Ins00: MOVE.L A1,V_RBufWrt(A2) update pointer
  1025.  MOVEA.L (A7)+,A1 get data
  1026.  MOVE.W V_ProcID(A2),D0 process to receive signal
  1027.  BEQ.S Ins01
  1028.  MOVE.W V_SigCod(A2),D1
  1029.  CLR.W V_ProcID(A2)
  1030.  BRA SendSig
  1031.  
  1032. Ins01: MOVE.B V_XOFF(A2),D0
  1033.  BEQ.S Ins02 XOff disabled -->
  1034.  CMPI.W #70,V_InCnt(A2)
  1035.  BCS.S Ins02
  1036.  MOVE.B V_XOnFlg(A2),D1
  1037.  BNE.S Ins02
  1038.  BCLR #7,V_XOFF(A2)
  1039.  BSET #7,D0
  1040.  MOVE.B D0,V_XOnFlg(A2)
  1041.  MOVE.B V_IRQEn(A2),D0
  1042.  MOVE.L A5,-(A7)
  1043. *@ LEA D_DuImr(A6),A5
  1044. * ADDA.W V_IBase(A2),A5
  1045. *@ OR.B D0,(A5)
  1046. *@ MOVE.B (A5),IMR(A0)
  1047.  MOVEA.L (A7)+,A5
  1048.  NOP
  1049. Ins02: BTST #S_RxRDY,SRAB(A3)
  1050.  BEQ WakeUp
  1051.  BRA GetChar get next char already available
  1052.  
  1053. *********************************************
  1054. * Routines to perform Control Sequence Commands
  1055. *
  1056.  
  1057. Pause: TST.L V_DEV2(A2) address of attached device
  1058.  BEQ InsertCH
  1059.  move.l a0,-(a7)
  1060.  lea V_DEV2(A2),A0
  1061.  move.b d0,V_PAUS(A0)
  1062.  move.l (a7)+,a0
  1063. * MOVE.B D0,([V_DEV2,A2],V_PAUS)
  1064.  BRA InsertCH
  1065.  
  1066. CtrlC: MOVEQ #S$Intrpt,D1
  1067.  BRA.S CtrlCE
  1068.  
  1069. CtrlE: MOVEQ #S$Abort,D1
  1070.  
  1071. CtrlCE: MOVE.B D0,-(A7)
  1072.  MOVE.W V_LPRC(A2),D0 last active process ID
  1073.  BSR SendS00
  1074.  MOVE.B (A7)+,D0
  1075.  BRA InsertCH
  1076.  
  1077. XOn: BCLR #0,V_Flag(A2)
  1078.  TST.B V_Flag(A2)
  1079.  BNE.S XEnd --> char to write in buffer
  1080.  MOVE.B V_IRQEn(A2),D0
  1081.  MOVE.L A5,-(A7)
  1082. *@ LEA D_DuImr(A6),A5
  1083. * ADDA.W V_IBase(A2),A5
  1084. *@ OR.B D0,(A5)
  1085. *@ MOVE.B (A5),IMR(A0)
  1086.  MOVEA.L (A7)+,A5
  1087.  NOP
  1088.  BTST #S_TxRDY,SRAB(A3)
  1089.  BEQ.S XEnd no -->
  1090.  BRA TxIRQ
  1091.  
  1092. XOff: BSET #0,V_Flag(A2)
  1093. XEnd: MOVEQ #0,D1
  1094.  RTS
  1095.  
  1096.  ends
  1097.  
  1098. * E O F *
  1099.