1 ; ***********************************************************
  2 ; *                                                         *
  3 ; * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 ; *                                                         *
  5 ; * Copyright, (C) Honeywell Information Systems Inc., 1986 *
  6 ; *                                                         *
  7 ; ***********************************************************
  8 
  9 page 55,132
 10 
 11 ; HISTORY COMMENTS:
 12 ;  1) change(86-04-01,McGinn), approve(87-07-13,MCR7580),
 13 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 14 ;     Created.
 15 ;  2) change(86-04-27,Westcott), approve(87-07-13,MCR7580),
 16 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 17 ;     Support macros.
 18 ;  3) change(86-09-09,Flegel), approve(87-07-13,MCR7580),
 19 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 20 ;     Support for checking for length field in test
 21 ;     for protocol mode.
 22 ;  4) change(86-09-15,Flegel), approve(87-07-13,MCR7580),
 23 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 24 ;     Change check for checksum to look for CRC char
 25 ;     of reset request packet.
 26 ;  5) change(86-12-09,Flegel), approve(87-07-13,MCR7580),
 27 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 28 ;     Removed packetize flag setting so that it can
 29 ;     be left to mio to set when all is peachy.
 30 ;  6) change(87-03-24,Flegel), approve(87-07-13,MCR7580),
 31 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 32 ;     Changed to look for r_EOP character as the
 33 ;     EOP rather than hardcoding a <LF>
 34 ;  7) change(87-04-03,Flegel), approve(87-07-13,MCR7580),
 35 ;     audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
 36 ;     Corrected reset packet testing in get_inbuff
 37 ;     to account for error characters in inbuff
 38 ;                                                      END HISTORY COMMENTS
 39 
 40 ;/* : FUNCTION
 41 ;
 42 ;This is a collection of routines which are used for buffer manipulations.
 43 ;*/
 44 
 45 include dos.mac
 46 include mowsdefs.mac
 47 include ws_buf.mac              ; circular buffer macros
 48 include rs232err.mac
 49 
 50 SOP          = 1                ; definition of a reset packet
 51 RSTREQ       = 32               ;    type field
 52 LENCHR       = 37               ;    length field
 53 CRCCHAR      = 58               ;    CRC field
 54 dseg
 55 
 56 ;---------- Public Declarations
 57 
 58 public put_inbuff
 59 public get_inbuff
 60 public len_inbuff
 61 public init_inbuff
 62 
 63 extrn inbuff:word
 64 extrn packet_mode:word
 65 extrn r_EOP:byte
 66 extrn datab:word
 67 endds
 68 
 69 page
 70 
 71 pseg
 72 
 73 ;/* : PROCEDURE FUNCTION (init_inbuff):
 74 ;
 75 ;Initialize the input buffer, and place/remove an initial character to "get
 76 ;the buffer going".
 77 ;*/
 78 
 79 init_inbuff proc near
 80 
 81         init_buf inbuff                     ; Initialization macro
 82         mov     al,'a'
 83         xor     ah,ah
 84         call    put_inbuff                  ; Put a test character in
 85         call    get_inbuff                  ; Get it out
 86 
 87 init_inbuff endp
 88 
 89 
 90 ;/* : PROCEDURE FUNCTION (put_inbuff):
 91 ;
 92 ;Puts the character in AL in the input buffer.
 93 ;*/
 94 
 95 ;/* RETURNS:
 96 ;
 97 ;    ax = 0 for no error
 98 ;    ax = 1 for buffer overflow
 99 ;*/
100 
101 put_inbuff proc near
102 
103         push    si                          ; save registers
104         push    bx
105 
106         mov     bx,offset inbuff            ; bx = inbuff
107         mov     si, bin[bx]                 ; si = buffer_in
108         or      ah,ah                       ; error prefix?
109         jz      nopfx                       ;  YES - abort
110         mov     byte ptr ds:[si],ah         ;   NO - process character
111 
112 ;/* : inbuff = inbuff + 1
113 ;     if (inbuff is at end of buffer)
114 ;     - inbuff = start of buffer */
115 
116         inc     si                          ; inc counter
117         cmp     si,blast[bx]                ; buffer wrapping ?
118         jbe     short nae1                  ;   NO - continue
119         mov     si,bfirst[bx]               ;  YES - wrap counter
120 
121 ;/* : if (not overflow) store inbuff, clear error code, and return */
122 
123 nae1:
124         cmp     si, bout[bx]
125         je      ovf1                        ; if buffer full
126 
127 ; /* : inbuff = inbuff + 1
128 ;      if (inbuff is at end of buffer)
129 ;      - inbuff = start of buffer */
130 
131 nopfx:
132         cmp     datab,DATA7                 ; if data7 then mask bit 8
133         jne     no_mask
134         and     al,7Fh                      ; mask data8 bit
135 
136 no_mask:
137         mov     byte ptr ds:[si],al
138 
139         inc     si                          ; inc counter
140         cmp     si,blast[bx]                ; wrapped buffer ?
141         jbe     short nae2                  ;   NO - continue
142         mov     si,bfirst[bx]               ;  YES - wrap counter
143 
144 ;/* : if (not overflow) store inbuff, and return */
145 
146 nae2:
147         cmp     si, bout[bx]                ; buffer full ?
148         je      ovf1                        ;  YES - overflow error
149 
150         mov     bin[bx],si                  ; reset the in counter
151 
152         pop     bx                          ; restore registers
153         pop     si
154         ret
155 
156 ;/* : else store overflow flag in buffer */
157 
158 ovf1:
159         mov     si,bin[bx]                  ; restore original in pointer
160         dec     si
161         cmp     si,bfirst[bx]
162         ja      ovf2
163         mov     si,blast[bx]
164 
165 ovf2:
166         mov     byte ptr ds:[si],5          ; overflow flag = 5
167         pop     bx
168         pop     si
169         ret
170 
171 put_inbuff endp
172 
173 ; : END put_buffer
174 
175 ;/* : PROCEDURE FUNCTION (get_inbuff):
176 ;
177 ;Get the next character from the rsr232 input circular buffer if MOWSE is not
178 ;in packet mode and a SOP character is received, return with no data to the
179 ;user until 4 characters have been accumulated in the buffer. If these 4
180 ;characters constitute a valid MOWSE RST packet, enter packet mode and give
181 ;the characters to the caller. If no SOP is found or if the SOP is not the
182 ;start of a RST packet, then just give the current charcter to the caller.
183 ;*/
184 
185 ;/* RETURNS:
186 ;
187 ;   Carry flag SET, if data available
188 ;   Carry flag CLEAR, if no data available
189 ;*/
190 
191 get_inbuff proc near
192 
193 ;/* : check for empty buffer */
194 
195         push    si
196         push    bx
197         mov     bx, offset inbuff
198         mov     si,bout[bx]
199         cmp     si,bin[bx]
200         jne     bnemp1
201         jmp     bemp2
202 
203 ;/* : if (buffer not empty) get character into AX */
204 
205 bnemp1:
206         mov     al,byte ptr ds:[si]
207 
208 ;/* : outbuff = outbuff + 1
209 ;     - if (outbuff = end of buffer) outbuff = start of buffer
210 ;     - if not in packet mode, look for reset packet */
211 
212         inc     si
213         cmp     packet_mode,0
214         jne     in_packet_mode
215 
216         cmp     al,SOP
217         jne     in_packet_mode              ; if not a start of (reset) packet
218 
219         mov     ax,bin[bx]
220         sub     ax,bout[bx]
221         jge     rst99
222         add     ax,bsize[bx]
223 
224 rst99:  cmp     ax,5                        ; must be at least 5 characters in reset packet
225         jl      bemp2                       ; return nothing to caller until 4 chars available
226 
227         cmp     si,blast[bx]
228         jbe     rst1
229         mov     si,bfirst[bx]
230 
231 rst1:
232         call    next_char                   ; get next valid char
233         call    chk_index                   ; make sure valid character
234         jnc     bemp2
235         cmp     al,RSTREQ
236         jne     givechar                    ; not a reset packet
237         inc     si
238         cmp     si,blast[bx]
239         jbe     rst2
240         mov     si,bfirst[bx]
241 
242 rst2:
243         call    next_char                   ; get next valid char
244         call    chk_index                   ; make sure valid character
245         jnc     bemp2
246         cmp     al,LENCHR
247         jne     givechar                    ; not a reset packet
248         inc     si
249         cmp     si,blast[bx]
250         jbe     rst3
251         mov     si,bfirst[bx]
252 
253 rst3:
254         call    next_char                   ; get next valid char
255         call    chk_index                   ; make sure valid character
256         jnc     bemp2
257         cmp     al,CRCCHAR
258         jne     givechar                    ; not a reset packet
259         inc     si
260         cmp     si,blast[bx]
261         jbe     rst4
262         mov     si,bfirst[bx]
263 
264 rst4:
265         call    next_char                   ; get next valid char
266         call    chk_index                   ; make sure valid character
267         jnc     bemp2
268         cmp     al,r_EOP
269         jne     givechar                    ; not a reset packet
270         mov     packet_mode,1               ; reset received, enter packet mode
271 
272 givechar:
273         mov     si,bout[bx]
274         mov     al,byte ptr ds:[si]
275         inc     si
276 
277 in_packet_mode:
278         cmp     si,blast[bx]
279         jbe     nae4
280         mov     si,bfirst[bx]
281 
282 nae4:
283         mov     bout[bx],si
284         jmp     bnemp2
285 
286 ;/* : if (buffer empty) clear AX, and return */
287 
288 bemp2:
289         pop     bx
290         pop     si
291         clc                                 ; CLEAR carry flag to indicate no data
292         ret
293 
294 bnemp2:
295         pop     bx
296         pop     si
297         stc                                 ; SET carry flag to indicate data available
298         ret
299 
300 get_inbuff endp
301 
302 ;/* : END get_buffer */
303 
304 ;/* : PROCEDURE FUNCTION (len_inbuff):
305 ;
306 ; Returns the number of characters in the buffer in AX.
307 ;*/
308 
309 len_inbuff proc near
310 
311         len_buf inbuff
312         ret
313 
314 len_inbuff endp
315 
316 ;/* : END get_length */
317 
318 ;/* : PROCEDURE FUNCTION (chk_index):
319 ;
320 ; Test if the current value of si is within the current inbuffer.
321 ;
322 ; carry flag = 1: valid index
323 ;            = 0: invalid index
324 ;*/
325 
326 chk_index proc near
327 
328         push    ax
329         mov     ax,bin[bx]
330         cmp     ax,bout[bx]                 ; in < out ?
331         jb      reverse_test                ;  YES - reverse test
332 
333         cmp     si,bout[bx]                 ; ?????O----Ixxxxx
334         jb      invalid_test                ; ^^^^^
335 
336         cmp     si,bin[bx]                  ; xxxxxO----I?????
337         jb      valid_test                  ; ^^^^^^^^^^
338         jmp     invalid_test
339 
340 reverse_test:
341 
342         cmp     si,bin[bx]                  ; -----I????O-----
343         jb      valid_test                  ; ^^^^^
344 
345         cmp     si,bout[bx]                 ; -----I????O-----
346         jb      invalid_test                ; ^^^^^^^^^^
347 
348 valid_test:
349         stc                                 ; Carry = 1, passed
350         pop     ax
351         ret
352 
353 invalid_test:
354         clc                                 ; Carry = 0, failed
355         pop     ax
356         ret
357 
358 chk_index endp
359 
360 ;/* : END get_length */
361 
362 ;/* : PROCEDURE FUNCTION (next_char)
363 ;
364 ; Returns the next valid character in the inbuff thus skipping over error escape
365 ; characters.
366 ;*/
367 
368 next_char proc near
369 
370 try_char:
371         mov     al,byte ptr ds:[si]         ; get current char
372 
373         cmp     al,ESCAPE_STATUS            ; escape char ?
374         ja      valid_char                  ;   NO - then current is OK
375         je      esc_chr                     ;  YES - then next char is valid
376 
377         cmp     al,LINE_STATUS              ; line_status char ?
378         jb      valid_char                  ;   NO - then current is OK
379 
380 skip_2:
381         inc     si                          ; increment index
382         cmp     si,blast[bx]
383         jbe     skip_1
384         mov     si,bfirst[bx]
385 
386 skip_1:
387         inc     si                          ; increment index
388         cmp     si,blast[bx]
389 ;       jbe     next_char
390         jbe     try_char
391         mov     si,bfirst[bx]
392 
393         jmp     try_char                    ; repeat as this may be another escape
394 ;       jmp     next_char                   ; repeat as this may be another escape
395 
396 esc_chr:
397         inc     si                          ; increment index
398         cmp     si,blast[bx]
399         jbe     no_wrap
400         mov     si,bfirst[bx]
401 no_wrap:
402         mov     al,byte ptr ds:[si]         ; get current char
403 
404 
405 valid_char:
406 
407         ret
408 
409 next_char endp
410 
411 ;/* : END next_char */
412 
413         endps
414         end