home *** CD-ROM | disk | FTP | other *** search
- page
- ;***********************************************************
- ;** **
- ;** Device Driver for RS232 communications **
- ;** Copyright (C) Texas Instruments 1986 **
- ;** Author: Greg Haley **
- ;** revisor: Joe McDaniel, Fein-Marquart **
- ;** **
- ;** THIS SOURCE CODE MAY BE DISTRIBUTED AND MODIFIED **
- ;** ONLY IF THE ORIGINAL COPYRIGHT AND AUTHOR CREDITS **
- ;** REMAIN INTACT. **
- ;** **
- ;** Project Start Date: 09/09/86 **
- ;** **
- ;** Re: 10/14/86 by Greg Haley **
- ;** Added more delays (jmp $+2) for more tolerant **
- ;** timing. Also increased stacks to 80 words for **
- ;** Business Pro compatibility. **
- ;** **
- ;** Re: 10/15/86 by Greg Haley **
- ;** The COMM chip is no longer initialized on every **
- ;** write request. **
- ;** **
- ;** Re: 10/23/86 by Greg Haley **
- ;** Added code to block interrupts while setting up **
- ;** and restoring the stack. **
- ;** **
- ;** Re: 11/07/86 by Greg Haley **
- ;** Added option to echo RS232 I/O to the CRT. **
- ;** **
- ;** Re: 11/13/86 by Greg Haley **
- ;** Save SI and AX when calling DOS fast write. **
- ;** Changed SAR's and SAL's to SHR's and SHL's. **
- ;** Added keyboard input in parallel with RS232 input. **
- ;** **
- ;** Re: 11/20/86 by Greg Haley **
- ;** Modified I/O channel commands so that a more **
- ;** standard structure could be used, and to make it **
- ;** easier to add new commands in the future. Also, **
- ;** all machine dependent code was moved to a seperate **
- ;** file to allow new machines to be added much more **
- ;** easily. **
- ;** **
- ;** Re: 12/29/86 by Greg Haley **
- ;** Fixed bug in XON-XOFF busy handling where XON **
- ;** was not sent to reset the busy condition. **
- ;** **
- ;** Re: 8/10/87 by Joe McDaniel **
- ;** 1. Fixed bugs in xon/xoff handling. It now works **
- ;** 2. Removed echoing options and keyboard input **
- ;** 3. Added interrupt driven transmit **
- ;** 4. Fixed bugs with RAW mode calls **
- ;** 4. Removed the TI version as I had no way to test **
- ;** whether it would still work. **
- ;** 5. Fixed the 19,200 baud stuff **
- ;** 6. Fixed circular buffer bugs **
- ;***********************************************************
-
- cr equ 13
- lf equ 10
-
- com1_tbl: ;header for device
- dw -1
- dw -1
- dw 1100000000000000B ; CHAR device with I/O control
- dw strategy
- dw entry
- db 'AUX ' ; Device name to use
-
- ; command jump table
- cmdtbl:
- dw init
- dw exit
- dw exit
- dw ioctl_in
- dw read
- dw nd_read
- dw input_status
- dw input_flush
- dw write
- dw write
- dw output_status
- dw exit
- dw ioctl_out
- dw exit ; open
- dw exit ; close
- dw exit
- dw exit
-
- oldss dw 0 ; Old SS reg
- oldsp dw 0 ; Old SP reg
- dw 80 dup (?) ; New stack
- e_stack label word
- ptrsav dd 0 ; DOS cmd block pointer
- init_once db 0 ; flag for init
- dcw_len db 0 ; DCW (0) or Length (not 0) mode
- tx_cnt dw 0 ; count of bytes sent
- page
- ;***********************************************************
- ;** Device Driver Entry **
- ;***********************************************************
- cmdlen = 0 ;length of this command
- unit = 1 ;sub unit specifier
- cmd = 2 ;command code
- status = 3 ;status
- media = 13 ;media descriptor
- trans = 14 ;transfer address
- count = 18 ;count of blocks or characters
- start = 20 ;first block to transfer
-
- ;***********************************************************
- ;** Strategy Routine **
- ;***********************************************************
- stratp proc far
-
- strategy:
- mov word ptr cs:[ptrsav],bx
- mov word ptr cs:[ptrsav+2],es
- ret
-
- stratp endp
-
- ;***********************************************************
- ;** Entry Routine **
- ;***********************************************************
- entry:
- cli ; disable ints
- mov cs:word ptr oldss,ss
- mov cs:word ptr oldsp,sp
- mov sp,cs
- mov ss,sp
- mov sp,offset e_stack
- sti ; enable ints
- push si
- push ax
- push cx
- push dx
- push di
- push bp
- push ds
- push es
- push bx
-
- lds bx,cs:[ptrsav] ;get pointer to i/o packet
- mov al,byte ptr ds:[bx].cmd ; al = command
-
- cbw
- mov si,offset cmdtbl
- add si,ax
- add si,ax
- cmp al,16
- ja cmderr
-
- les di,dword ptr ds:[bx].trans ; es:di = tranfer address
- mov cx,ds:[bx].count ; cx=count
-
- push cs
- pop ds
- cld
-
- assume ds:code
-
- jmp word ptr [si] ;go do command
-
- page
- ;***********************************************************
- ;** Device Driver Exit **
- ;***********************************************************
- bus$exit: ;device busy exit
- mov ah,00000011b
- jmp short done
-
- cmderr:
- mov al,3 ;unknown command error
-
- err$exit:
- mov ah,10000001b ;mark error return
- jmp short done
-
- exitp proc far
-
- exit:
- mov ax,0000000100000000b ; mark as done
- done:
- lds bx,cs:[ptrsav]
- mov ds:word ptr [bx].status,ax ;mark operation complete
-
- pop bx
- pop es
- pop ds
- pop bp
- pop di
- pop dx
- pop cx
- pop ax
- pop si
-
- ; restore stack
- cli ; disable ints
- mov ss,cs:word ptr oldss
- mov sp,cs:word ptr oldsp
- sti ; enable ints
-
- ret ;restore regs and return
- exitp endp
-
- page
- ;***********************************************************
- ;** Write Routine **
- ;** **
- ;** ES:DI contain xfer adrs on entry **
- ;** CX contains num chars to write **
- ;** **
- ;** **
- ;***********************************************************
- write proc near
-
- jcxz write_2 ; if nothing to send, exit immediately
-
- push es ; Move pointer to DS:SI
- pop ds
- mov si,di
-
- mov dx,cs:word ptr tq_head ; get transmitter head into dx
-
-
- send_chars:
- mov ax,tran_limit ; see if room for more
- cli
- sub ax,cs:tq_len ; subtract current count
- sti
- jne write_1 ; there is still room
-
- jmp write_2 ; no more room
-
- write_1:
- lodsb ; al now has char
- mov di,offset tqueue ; Queue char
- add di,dx ; add in tq_head value
- mov cs:byte ptr [di],al ; store char in trans_buffer
- inc dx ; update header pointer, too
- and dx,tran_limit ; and adjust for overflow
- mov cs:word ptr tq_head,dx ; update head
- cli
- inc cs:word ptr tq_len ; Adjust queue length
- sti
-
- loop send_chars ; look for more chars
-
- write_2:
- call update_count ; sets count=count-cx
-
- cli
- cmp cs:byte ptr xmit_busy,0 ; is transmitter busy?
- je write_3
- jmp write_4 ; it was, so we can just exit
-
- write_3:
- call xmit_mt ; force first character out
- write_4:
- sti
- jmp exit
- write endp
-
- page
- ;***********************************************************
- ;** Non Destructive Read Routine **
- ;** **
- ;** On entry, ES points to buffer segment **
- ;***********************************************************
- nd_read proc near
- mov di,13 ; point to byte buffer
-
- cmp cs:word ptr rq_len,0 ; Any chars in receive buffer?
- jnz nd_read_1 ; Yes, continue
- mov ah,00000011b ; Set busy & done
- jmp done ; We're done
-
- nd_read_1:
- mov bx,offset rqueue ; Get queue ptr
- mov dx,cs:word ptr rq_tail
- add bx,dx ; point at char
- mov al,byte ptr[bx] ; al now has char
-
-
- stosb ; store char in buffer
- jmp exit
- nd_read endp
-
- page
- ;***********************************************************
- ;** Get Input Status **
- ;***********************************************************
- input_status proc near
- cmp cs:word ptr rq_len,0 ; Any chars in receive buffer?
- jnz xit_in_stat ; Yes, continue
- mov ah,00000011b ; No, set busy & done
- jmp done ; We're done
-
- xit_in_stat:
- jmp exit ; Normal exit code
- input_status endp
-
- page
- ;***********************************************************
- ;** Flush Input Buffer **
- ;***********************************************************
- input_flush proc near
- mov cs:word ptr rq_head,0 ; Head = 0
- mov cs:word ptr rq_tail,0 ; Tail = 0
- mov cs:word ptr rq_len,0 ; make queue length 0
- jmp exit ; Normal exit code
- input_flush endp
-
- page
- ;***********************************************************
- ;** Get Output Status **
- ;***********************************************************
- output_status proc near
- cmp cs:byte ptr t_busy,0 ; Are we busy?
- je xit_out_stat ; No, continue
- mov ah,00000011b ; Set busy & done
- jmp done ; We're done
-
- xit_out_stat:
- jmp exit ; Normal exit code
- output_status endp
-
- page
- ;***********************************************************
- ;** Read Routine **
- ;** **
- ;** ES:DI contain xfer adrs on entry **
- ;** CX contains num chars requested **
- ;***********************************************************
- read proc near
- cli
- mov ax,cs:word ptr rq_len ; Any chars in recv buffer?
- sti
- or ax,ax
- jnz read_1 ; Yes, continue
- call update_count ; count=count-cx (therefore, 0)
- jmp exit ; We're done
-
- read_1:
- ; figure out how many chars to get
- cmp ax,cx ; More than DOS buffer?
- jg read_2 ; Yes, CX already has count
- mov cx,ax ; No, only send what we have
- lds bx,cs:[ptrsav] ;get pointer to i/o packet
- mov word ptr ds:[bx].count,cx ;cx = count of bytes remaining
- ;to process
-
- read_2:
- mov dx,cs:word ptr rq_tail
-
- read_3:
- mov si,offset rqueue ; Get queue ptr
- add si,dx ; point at char
- mov al,cs:byte ptr[si] ; al now has char
-
-
- stosb ; store char in buffer
- inc dx
- and dx,recv_limit ; wrap if >= limit
- mov cs:word ptr rq_tail,dx ; update tail
- cli
- dec cs:word ptr rq_len ; Adjust queue length
- sti
- loop read_3 ; Loop again
-
- call update_count ; count=count-[cx]
-
- ; reset busy if we can
- cli
- cmp cs:word ptr rq_len,not_busy_len ; Room for more chars?
- sti
- jg read_4 ; No, skip
- mov cs:byte ptr r_busy,0 ; Yes, reset busy
- mov al,xon
- cli
- call send_xon ; Send XON char if needed
- sti
- read_4:
-
- jmp exit
- read endp
-
- page
- ;***********************************************************
- ;** Write I/O Control Channel **
- ;** **
- ;** ES:DI contain xfer adrs on entry **
- ;** CX contains count **
- ;***********************************************************
- ioctl_out proc near
- push es ; Move pointer to DS:SI
- pop ds
- mov si,di
-
- cmp cx,2 ; Is it a DCW?
- je ioo_1 ; Yes, continue
- cmp cx,1 ; Is it a CSB?
- jz ioo_nc0 ; Yes, continue
- jmp exit ; No, exit
-
- ioo_nc0:
- lodsb ; Yes, get the byte
-
- push cs ; DS = CS
- pop ds
-
- mov ah,al ; Update DCW/LEN mode
- and ah,00000100b
- mov dcw_len,ah
-
- test al,00000001b ; Drop RS232 signals?
- jnz ioo_nc1 ; No, skip
- call de_init ; Yes, disconnect
- mov byte ptr dcw_len,0 ; Reset to DCW mode
- ioo_nc1:
-
- test al,00000010b ; Flush input buffer?
- jz ioo_nc2 ; No, skip
- jmp input_flush ; Yes, go flush it
- ioo_nc2:
-
- jmp exit ; exit
- ioo_1:
- lodsw ; get DCW in AX
-
- ; make ds = cs
- push cs
- pop ds
-
- ; check for serial device
- test ah,80h ; Serial device?
- jnz ioo_2 ; Yes, continue
- jmp exit ; No, exit
- ioo_2:
-
- call set_dcw ; Go set DCW
-
- mov word ptr dcw,ax ; Save new DCW
- call init_comm ; init comm chip
- jmp exit
-
- ioctl_out endp
-
- page
- ;***********************************************************
- ;** Read I/O Control Channel **
- ;** **
- ;** ES:DI contain xfer adrs on entry **
- ;***********************************************************
- ioctl_in proc near
- cmp cx,2 ; Is it a word?
- je is_2byte ; Yes, go get it
- cmp cx,1 ; Is it a byte?
- jne ioi_xit ; No, exit
-
- xor al,al ; Clear status byte
- or al,cs:byte ptr m_stat ; Update current modem status
- stosb ; and pass it to DOS
- jmp exit
-
- is_2byte:
- cmp cs:byte ptr dcw_len,0 ; DCW mode?
- jz ioi_1 ; Yes, get DCW
-
- mov ax,cs:rq_len ; No, get receive queue length
- jmp short ioi_2
-
- ioi_1:
- mov ax,cs:dcw ; Get DCW
- ioi_2:
- stosw ; and pass it to DOS
-
- ioi_xit:
- jmp exit
- ioctl_in endp
-
- page
- ;***********************************************************
- ;** Return Number of Chars Processed **
- ;** **
- ;** CX contains number of characters NOT processed **
- ;***********************************************************
- update_count proc near
- push ds
- push bx
-
- lds bx,cs:[ptrsav] ;get pointer to i/o packet
- sub word ptr ds:[bx].count,cx ;cx = count of bytes remaining
- ;to process
-
- pop bx
- pop ds
- ret
- update_count endp
-