; ============================================================================
;
; LT-DOS - COM port device
;
; ============================================================================
; ----------------------------------------------------------------------------
; Device service tables
; ----------------------------------------------------------------------------
; ------------- AUX, COM service table
FNCCOM: db 11 ; number of functions
dw DevIntOK ; 0 init
dw DevIntOK ; 1 media check
dw DevIntOK ; 2 build BPB
dw DevIntInv ; 3 IOCTL input
dw COMRData ; 4 read data
dw COMRTest ; 5 test read
dw COMRStatus ; 6 input status
dw COMRFlush ; 7 flush input
dw COMWData ; 8 write data
dw COMWData ; 9 write with verify
dw COMWState ; 10 output status
; ----------------------------------------------------------------------------
; Device interrupt service - COM read data
; ----------------------------------------------------------------------------
; INPUT: CX = number of characters to read
; ES:DI = data buffer
; DS = data segment
; OUTPUT: AX = status word
; DESTROYS: BX, DX, DS
; ----------------------------------------------------------------------------
COMRData: jcxz COMRData4 ; there are no data to read
COMRData2: call COMRChar ; read character from COM
jc COMRData5 ; error
cld ; direction up
stosb ; store character to buffer
loop COMRData2 ; read next character
COMRData4: mov ah,S_DONE ; status OK
ret ; return from interrupt
COMRData5: mov al,ERR_READ ; read error
COMError: jmp DevIntError ; read/write error
; ----------------------------------------------------------------------------
; Device interrupt service - COM test read
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AX = status word
; DESTROYS: BX, DX, DS
; ----------------------------------------------------------------------------
COMRTest: call COMRTestChar ; test character
jc COMRTest2 ; no character ready
lds bx,[Strat] ; DS:BX <- strategy address
mov [bx+13],al ; output character
COMRTestOK: mov ah,S_DONE ; status OK
ret
LPTRTest:
COMRTest2: mov ah,S_DONE+S_BUSY ; status - device not ready
ret
; ----------------------------------------------------------------------------
; Device interrupt service - COM input status
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AX = status word
; DESTROYS: BX, DX
; ----------------------------------------------------------------------------
COMRStatus: call COMRTestChar ; test character
jc COMRTest2 ; no character ready
jmp short COMRTestOK; status OK
; ----------------------------------------------------------------------------
; Device interrupt service - COM flush input
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AX = status word
; DESTROYS: BX,DX
; ----------------------------------------------------------------------------
COMRFlush: call COMRTestChar ; any character ready?
jc COMRTestOK ; no character
call COMRChar ; input chracter from COM
jmp short COMRFlush ; next character
; ----------------------------------------------------------------------------
; Device interrupt service - COM write data
; ----------------------------------------------------------------------------
; INPUT: CX = number of characters to write
; ES:DI = data buffer
; DS = data segment
; OUTPUT: AX = status word
; DESTROYS: BX, DX
; ----------------------------------------------------------------------------
COMWData: jcxz COMWDataOK ; there are no data to write
COMWData2: mov al,[es:di] ; AL <- character to write
inc di ; increase pointer
call COMWChar ; write character to COM
mov al,ERR_WRITE ; write error
jc COMError ; error
loop COMWData2 ; write next character
COMWDataOK: mov ah,S_DONE ; status OK
ret ; return from interrupt
; ----------------------------------------------------------------------------
; Device interrupt service - COM output status
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AX = status word
; DESTROYS: DX
; ----------------------------------------------------------------------------
; ------------- Get COM state
COMWState: mov ah,3 ; AH <- function code
call COMFnc ; test COM state
; ------------- Test COM send state
and ax,2020h ; mask modem and link send state
cmp ax,2020h ; is COM ready to send?
je COMWDataOK ; COM is ready to send
mov ah,S_DONE+S_BUSY ; status - device not ready
ret
; ----------------------------------------------------------------------------
; COM read character
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AL = character
; CY = error or no character
; DESTROYS: AH, BX, DX
; ----------------------------------------------------------------------------
; ------------- Read character from buffer
COMRChar: mov bx,[DevInx] ; BX <- number of COM port
mov al,0 ; flag - no character is in buffer
xchg al,[COMBuffOK+bx] ; get flag
or al,al ; is there a character?
mov al,[COMBuff+bx] ; AL <- character from buffer
jnz COMRChar8 ; there is a valid character
; ------------- Read character from COM
mov ah,2 ; AH <- funtion code
call COMFnc ; input character from COM port
; ------------- Error
and ah,0eh ; any error?
jz COMRChar8 ; character is OK
stc ; set error flag
COMRChar8: ret
; ----------------------------------------------------------------------------
; COM test character
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; OUTPUT: AL = character
; CY = no character
; DESTROYS: AH, BX, DX
; ----------------------------------------------------------------------------
; ------------- Test character from buffer
COMRTestChar: mov bx,[DevInx] ; BX <- number of COM port
cmp byte [COMBuffOK+bx],0 ; is there a character?
mov al,[COMBuff+bx] ; AL <- character from buffer
jne COMRTestChar8 ; there is a valid character
; ------------- Test COM port
mov ah,3 ; AH <- function code
call COMFnc ; test COM port
and ax,120h ; mask modem and link ready flags
cmp ax,120h ; is modem and link ready to receive?
je COMRTestChar3 ; character is ready
COMRTestChar2: stc ; flag - character is not ready
ret
; ------------- Input character from COM port
COMRTestChar3: mov ah,2 ; AH <- function code
call COMFnc ; input character from COM
and ah,0eh ; any error?
jnz COMRTestChar2 ; error
; ------------- Store character to buffer
mov [COMBuff+bx],al ; store character
mov byte [COMBuffOK+bx],1 ; flag that there is a char
COMRTestChar8: clc ; flag - a character is ready
ret
; ----------------------------------------------------------------------------
; COM write character
; ----------------------------------------------------------------------------
; INPUT: AL = character
; DS = data segment
; OUTPUT: CY = error
; DESTROYS: AX, DX
; ----------------------------------------------------------------------------
COMWChar: mov ah,1 ; AH <- function code
call COMFnc ; write character to COM
test ah,80h ; TIME-OUT error?
jz COMWChar2 ; it is OK
stc ; error flag
COMWChar2: ret
; ----------------------------------------------------------------------------
; COM function
; ----------------------------------------------------------------------------
; INPUT: AH = function code
; DS = data segment
; OUTPUT: AH = status
; DESTROYS: AL, DX
; ----------------------------------------------------------------------------
COMFnc: mov dx,[DevInx] ; DX <- number of COM port
int 14h ; COM function
ret
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
COMBuffOK: db 0,0,0,0 ; COM flags, 1=character is in buffer
COMBuff: db 0,0,0,0 ; COM data buffers (COM1 to COM4)
|