Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

IO_COM.ASM

Ovladač komunikačního portu

Soubor IO_COM.ASM obsahuje ovladač sérovového komunikačního portu COM. Data jsou z COM portu čtena po blocích zadané délky funkcí COMRData. Jednotlivé bajty jsou z portu načítány funkcí COMRChar a ukládány do datového bufferu. Funkce COMRChar se nejdříve pokusí načíst bajt z pomocného bufferu COMBuff, který může obsahovat data z případného předchozího testu bajtu z portu. COMBuffOK je pole příznaků udávající, že v bufferu je pro příslušný COM port uložen platný bajt.

Funkce COMRTest slouží k testu bajtu připraveného na COM portu. K zjištění připraveného znaku se použije funkce COMRTestChar. Tato funkce se nejdříve pokusí načíst bajt z bufferu COMBuff. Není-li zde žádný bajt, otestuje nejdříve stav modemu a linky, zda je možný příjem bajtu. Bajt z portu COM přijme a uloží ho do bufferu COMBuff k příštímu zpracování. Není-li žádný bajt připraven, navrátí chybu "Zařízení nepřipraveno".

Funkce COMRFlush vyprázdní vstupní buffer COM portu. Opakovaně testuje a čte data z portu COM, dokud nějaká data jsou připravena. Načtená data zahazuje.


; ============================================================================
;
;                            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)

Pomocí funkce COMWData je možné odeslat blok dat z datového bufferu na COM port. Funkce používá k zápisu jednoho bajtu funkci COMWChar.

Zpět na stránku systému LT-DOS