1 ; ***********************************************************
  2 ; *                                                         *
  3 ; * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 ; *                                                         *
  5 ; * Copyright, (C) Honeywell Information Systems Inc., 1986 *
  6 ; *                                                         *
  7 ; ***********************************************************
  8 
  9 ; HISTORY COMMENTS:
 10 ;  1) change(87-07-04,Flegel), approve(87-07-13,MCR7580),
 11 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 12 ;     Created.
 13 ;  2) change(88-02-11,Lee), approve(88-02-29,MCR7853),
 14 ;     audit(88-03-10,Nakaska):
 15 ;     BREAK period made to be based on calculated number of characters
 16 ;     sent to the RS232 port while the break bit is set
 17 ;                                                      END HISTORY COMMENTS
 18 ;
 19 ;FUNCTION (line_break)
 20 ;
 21 ; Send a hard break out the rs232port.  This is used when Multics MOWSE has
 22 ; not been attached.
 23 
 24 ;*/
 25 
 26 
 27 include dos.mac                   ;Lattice include file
 28 include mowsdefs.mac              ;Constant values
 29 include ws_buf.mac                ; circular buffer macros
 30 
 31 ;*******************************************************************
 32 ;                            DATA
 33 ;*******************************************************************
 34 dseg
 35 
 36 ; ----- Constants ------------------------------------------------------------
 37 
 38 MCROUT2_MASK = 11110111b          ; Mask for the out 2 bit in MCR
 39 BRKVAL  = 01000000b               ; Break bit in Line control register
 40 DATA_BITS = 8
 41 START_BITS = 1
 42 
 43 ; ----- Data Segment ---------------------------------------------------------
 44 
 45 frame_bits  dw  11                ; holds number of bits in frame per character
 46 
 47 ;-------- External declarations
 48 
 49 extrn  COM_PORT:word
 50 extrn  lineparm:byte              ; line parameter values from initialize_mowse
 51 
 52 ;-------- Public Declarations
 53 
 54 public frame_bits
 55 
 56 endds
 57 
 58 page
 59 ;*******************************************************************
 60 ;                             MAIN
 61 ;*******************************************************************
 62 pseg
 63 
 64 ;--------- External Procedures
 65 
 66 public line_break
 67 
 68 line_break proc near
 69         push    ax                ; save registers
 70         push    bx
 71         push    cx
 72         push    dx
 73 
 74 ; /* determine the baud rate by extracting from the lineparm variable */
 75 
 76         mov     al,lineparm       ; get line parameter values
 77         mov     cl,5              ; extract highest 3 bits of line parameter
 78         ror     al,cl             ;   (which specifies the baud)
 79         and     al,7              ; clear all but lowest 3 bits and see if zero
 80         jnz     calc_baud         ; 0=B110, 1=B150, 2=B300, ... 7=B9600
 81 
 82         mov     ax,110            ; baud is 110, set ax to baud 110
 83         jmp     short line_break_next
 84 
 85 calc_baud:
 86         mov     cl,al             ; baud is calculated = 75 * (2 ** cl)
 87         mov     ax,75
 88         shl     ax,cl
 89 
 90 ; /* now ax contains the baud number */
 91 ; /* determine bytes per quarter second from bits per second (baud) */
 92 ; /* determine number of bits per byte assuming: */
 93 ; /* 1 start bit, 8 data (or 7 data and 1 parity) bits, N stop */
 94 ; /* bits where N is taken from the line parameter value */
 95 
 96 line_break_next:
 97         push    ax                ; save baud
 98                                   ; bit 2 specifies number of stop bits:
 99                                   ;   clear is 1 stop bit, set is 2 stop bits
100         mov     al,lineparm       ; get line parameter values
101         ror     al,1              ; shift til stop bit is least significant bit
102         ror     al,1
103         and     al,1              ; mask out all other bits
104         inc     al                ; convert to actual number of stop bits
105 
106         mov     bx,DATA_BITS+START_BITS ; calculate bits per frame
107         mov     ah,0
108         add     bx,ax             ; add number of stop bits
109         shl     bx,1            ; multiply divisor by 4 to get bits per 1/4 sec
110         shl     bx,1
111         mov     frame_bits,bx     ; save in divisor location
112 
113         pop     ax                ; restore baud rate in ax
114         cwd                       ; sign extend ax into dx for division
115         div     frame_bits        ; divide to get characters per 1/4 second
116 
117         mov     cx,ax             ; load character count into loop counter
118 
119 ; disable modem interrupts which are normally generated when a character
120 ; is sent; the interrupts are handled by MOWSE which looks at the
121 ; output buffer for more characters to send
122 
123         mov     dx,COM_PORT       ; get modem control register to turn
124         add     dx,MCR            ;     modem interrupts off while doing
125         in      al,dx             ;     break
126 
127         push    ax                ; save current modem control setting
128         and     al,MCROUT2_MASK   ; clear the OUT 2 bit to disable ints.
129         out     dx,al             ; disable modem interrupts
130 
131         mov     dx,COM_PORT       ; port address in DX
132         add     dx,LCR
133         in      al,dx             ; get current setting
134         or      al,BRKVAL         ; set the send-break bits
135         out     dx,al             ; start the break
136 
137         push    ax                ; save LCR flags in al
138 
139         mov     al,0              ; set arbitrary character to send
140 
141 line_break_loop:
142         call    out_a_byte        ; send until specified number of
143         loop    line_break_loop   ;    characters reached
144 
145         pop     ax                ; restore LCR flags in al
146         xor     al,BRKVAL         ; clear the send-break bits
147         out     dx,al             ; stop the break
148 
149         pop     ax                ; restore modem control settings
150         mov     dx,COM_PORT       ; get address of MCR for
151         add     dx,MCR            ;    current COMM port
152         out     dx,al             ; restore the MCR settings
153 
154         pop     dx                ; restore registers
155         pop     cx
156         pop     bx
157         pop     ax
158         ret
159 line_break endp
160 
161 
162 ;FUNCTION (out_a_byte)
163 ;
164 ; Send a character out to the rs232port.  This routine simply returns
165 ; on a time out of the send.
166 ;
167 
168 out_a_byte proc near
169 
170         push ax
171         push bx
172         push cx
173         push dx
174 
175 
176 ;/* : Set up RS232 */
177 
178         mov     bl,al             ;Save char to bl temporarily
179         mov     dx,MCR            ;Modem control Register
180         add     dx,COM_PORT
181         mov     al,MCRREAD        ;Out2, DTR, RTS
182         out     dx,al
183         mov     dx,MSR            ;Modem status Register
184         add     dx,COM_PORT
185 
186 ;/* : Wait for CTS (Clear to send) */
187 
188 OB150:
189         sub     cx,cx             ;timeout count
190 
191 TIME_LOOP:
192         in      al,dx
193         test    al,MSRCTS         ;Clear to send?
194         jnz     SEND_CLEAR        ;yes
195         loop    TIME_LOOP         ;No, loop til timeout
196 
197 ;/* : Too long, exit */
198         jmp     short OBEXIT      ;And QUIT
199 
200 ;/* : Wait for THRE (Transmit Holding Register Empty) */
201 
202 SEND_CLEAR:
203         mov     dx,LSR            ;Line Status register
204         add     dx,COM_PORT
205         sub     cx,cx             ;Another time out
206 
207 STATUS_TIMING:
208         in      al,dx             ;LSR status
209         test    al,LSRTHRE        ;Transmit holding reg empty
210         jnz     SEND_CHAR         ;Yes
211         loop    STATUS_TIMING     ;No, loop til timeout
212 
213 ;/* : Too long, exit */
214         jmp     short OBEXIT      ;And QUIT
215 
216 ;/* : Get line status , send char */
217 
218 SEND_CHAR:
219         mov     ah,al             ;Get line status for return
220         and     ah,MASK7          ;mask bit 7
221         mov     al,bl             ;restore char to al
222         mov     dx,THR            ;transmit holding register
223         add     dx,COM_PORT
224         out     dx,al             ;Output it to RS232
225 
226 OBEXIT:
227         pop     dx                ;Restore Registers
228         pop     cx
229         pop     bx
230         pop     ax
231         ret
232 
233 out_a_byte endp
234 
235         endps
236         end
237