⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gwcom.asm

📁 DOS 6.22 的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	TITLE	GWCOM - OEM-indepedent Communications Routines

	PAGE	56,132

;***
; GWCOM.ASM - OEM-indepedent Communications Routines
;
;	Copyright <C> 1986 - 1988, Microsoft Corporation
;
; Purpose:
;	To provide the GW I/O dispatch routines for the serial
;	communications ports through calls to the OEM routines.
;
;******************************************************************************

	INCLUDE switch.inc
	INCLUDE rmacros.inc	

	useSeg	_BSS		
	useSeg	_DATA		
	useSeg	CONST		
	useSeg	DV_TEXT 	

	INCLUDE seg.inc 	
	INCLUDE baslibma.inc
	INCLUDE files.inc
	INCLUDE devdef.inc
	INCLUDE ascii.inc	;must follow devdef.inc
	INCLUDE addr.inc	;usercode header structure
	INCLUDE comdcb.inc	;DCB structure for comm device
	INCLUDE rtps.inc	; constants shared with QBI
	INCLUDE idmac.inc	

;	The following macros generate the dispatch target labels used
;	by the the I/O system one-time initialization(I) and dispatch
;	dispatch table entry(D).

ComDspLabels	MACRO	Ctype
	Cindex	= 0		;;value to pass to item generation macro

	REPT	NUM_RS232	;;one item for each comm device defined
	Cindex	= Cindex + 1	;;update the counter
	ComItem	Ctype,%Cindex	;;define item with type (I,C,D) and counter
	ENDM

	ENDM	;;ComDspLabels

ComItem	MACRO	Ctype,Cindex
	PUBLIC	B$&Ctype&_COM&Cindex ;;define PUBLIC (e.g., PUBLIC B$I_COM2)
B$&Ctype&_COM&Cindex:		 ;;define label (e.g., B$I_COM2:)
	ENDM	;;ComItem

sBegin	CONST			

CMERRT	DW	OFFSET B$ERR_IOE ;Other IO Error
	DW	OFFSET B$ERR_CBO ;buffer overflow error
	DW	OFFSET B$ERR_IOE ;parity error
	DW	OFFSET B$ERR_DTO ;device timeout
	DW	OFFSET B$ERR_DTO ;device timeout
	DW	OFFSET B$ERR_DTO ;device timeout

sEnd	CONST			

sBegin	_BSS			

	externB	B$CM1DCB		; defined in GWDATA.ASM
	externB	b$FILMOD	; defined in GWINI.ASM
	externB	b$PATHNAM	; defined in GWINI.ASM
	externW b$ComPort	;LLPARAM - save area for COMx I/O ports
	externB b$COM_DCB	;DCB for COM1 device

externD b$RECPTR		; pointer to random record
externW b$cbComBuffer		;combuffer size specified on QB command line
	staticW COMSAV,,2	;save area for b$ComPort across SHELL
	globalB b$COFlag,0,1	; Flag to indicate COM OPEN in progress

sEnd	_BSS			


sBegin	DV_TEXT 		
assumes CS,DV_TEXT		

	externNP B$FHHighAlloc
	externNP B$FHHighDealloc



;   Device Independent Interface

DSPMAC	MACRO	func
	DW	COM_&func	;;Define Dispatch Table for Specific Device
	ENDM

;	Communications Dispatch Table - must not be at offset 0.

ComDspLabels	D		;define dispatch table labels

	DSPNAM			;define dispatch table

	SUBTTL	Communications Generalized I/O Routines

	externNP B$DEVOPN
	externNP B$LHDALC_CPCT	
	externNP B$INICOM	
	externNP B$RECCOM	
	externNP B$SNDCOM	
	externNP B$STACOM	
	externNP B$TRMCOM	
	externNP B$BREAK_CHK
	externNP B$ERR_BFN	;Error routines - Bad File Name
	externNP B$ERR_DNA	;device unavailable error
	externNP B$ERR_FAO	;   File Already Open
	externNP B$ERR_CBO	;   Com Buffer Overflow
	externNP B$ERR_DTO	;   Device Time Out
	externNP B$ERR_IOE	;   Device Input Output Error
	externNP B$ERR_FC	;   Bad Function Call
	externNP B$ERR_OM_FH	; out of memory error

;	$I_COMx - called during BASIC initialization

;	Entry - DI = -2*device id

ComDspLabels	I		;define initialization labels

	PUSH	AX		;save registers...
	PUSH	DI
	CALL	GetComDCB	;DI points to device control block
	MOV	[DI].CD_CMWID,0FFH ;initial width is infinite
	MOV	[DI].CD_CMPOS,0	;initial position is zero
	MOV	[DI].CD_CMFDB,0 ;mark this device as available for open
	POP	DI		;restore registers...
	POP	AX
	RET			;return to caller

;***
; COM_OPEN - open an asynchronous communications device
;
; Entry:
;	AL = device id (negative number from DN_COM1 to DN_COMn)
;	BX = file number (0..n)
;	CX = random record size if [b$FILMOD] = random
;		 (if [CX] = 0, use default record size)
;	DI = device offset (2=COMD, 4=SCRN, etc.)
;	b$FILMOD = file mode
;		MD_SQI = 1 - sequential input
;		MD_SQO = 2 - sequential output
;		MD_RND = 4 - random
;		MD_APP = 8 - append
;	b$PATHNAM = null-terminated com options string (including "COMn:")
; Exit:
;	SI = pointer to FDB allocated
;*****************************************************************************


; Syntax:	OPEN "COMn:[SPEED][,[PARITY][,[DATA][,[STOP][,nonpos]]]]"

; Positional parameters:
;
;	SPEED	baud rate in bits per second
;	PARITY  N(none), E(even), O(odd), M(mark), S(space)
;	DATA    5, 6, 7, or 8 bits per character
;	STOP	1, 1.5, or 2 stop bits
;		Default for slower than 110 baud and 6, 7, or 8 data bits is 2.
;		Default for slower than 110 baud 5 data bits is 1.5.
;		Default for 110 baud or faster is 1.
;
; Nonpositional parameters:
;
;	RS	Suppress RTS (Request To Send).
;	OP[n]	Open timeout in milliseconds.
;	CS[n]   Clear-to-send (CTS) timeout in milliseconds.
;	DS[n]   Data-set-ready (DSR) timeout in milliseconds.
;	CD[n]	Carrier-detect (CD) timeout in milliseconds.
;	RB[n]	Size of receive buffer in bytes.
;	TB[n]	Size of transmit buffer in bytes.
;	LF	Transmit a line-feed following a carriage-return.
;	ASC	Open COM file in ASCII mode  | none => open in
;	BIN	Open COM file in binary mode | IBM mode

DbPub	<COM_OPEN>		
COM_OPEN:
	MOV	AH,BL		;[AH]=file number
	PUSH	AX		;save file number, device id
	PUSH	CX		;save variable record len (if random)
	CALL	GetComDCB	;AX = 0, 1, ... for COM1, COM2, ...
				;DI points to Device Control Block
	CMP	[DI].CD_CMFDB,0 ;see if device is opened to another file
	JE	NERFNO		;No ERror, File Not Open
	JMP	B$ERR_FAO	;File Already Opened
NERFNO:
	MOV	[DI].CD_DEVID,AL ;set unit field of Device Control Block

	MOV	SI,OFFSET DGROUP:b$PATHNAM+5 ; point to options
	CALL	ParseOpt	;parse options (fill in DCB fields)

	CALL	B$ComAlloc	;[2]allocate the comm buffer and fill in DCB

	MOV	[DI].CD_CMPOS,0 ;reset column to 0
	MOV	BX,DI		;BX points to DCB
DbAssertRelB	<[b$COFlag]>,E,0,DV_TEXT,<b$COFlag non-zero in COM_OPEN> ;
	INC	[b$COFlag]	; non-zero indicates COM OPEN in progress
	CALL	B$INICOM 	;call machine dependent OPEN routine
				;destroys FLAGS, AX..DX
DbAssertRelB	<[b$COFlag]>,B,2,DV_TEXT,<bad b$COFlag value in COM_OPEN> ;
	MOV	[b$COFlag],0	; be sure this is CLEARed on exit
	OR	AH,AH		;check for error during OPEN
	JZ	COMOPEN_NOERR	;if no error, then jump

	CALL	B$ComDealloc	;[2]deallocate the comm buffers

	INC	AH		;see if B$INICOM didn't like options
	JZ	ERCIFN		;bad file name error if illegal mode
	INC	AH		;test if device unavailable
	JZ	ERCDNA		;if so, then process error
	SUB	AH,2		;get back error code other than -1 or -2
	CALL	CKCMER		;check for device error code (will not return)

COMOPEN_NOERR:			
	POP	CX		;[CX]=record length
	CMP	b$FILMOD,MD_RND ; random open?
	JNE	NOTRND		; brif not
	INC	CX		; LEN parameter specified?
	LOOP	OPENIT		; brif so -- use that value for length
	MOV	CX,REC_LENGTH	; use default record length
	SKIP	2		; JMP OPENIT
NOTRND:				
	XOR	CX,CX		; don't need any buffer space for seq files
OPENIT:				
	POP	AX		; [AL]=device id, AH = file number
	MOV	DL,[DI].CD_CMWID ; [DL]=width from Device Control Block
	MOV	BL,AH
	XOR	BH,BH		; [BX]=file number
	MOV	AH,MD_RNDCH+MD_RND+MD_APP+MD_SQO+MD_SQI ; allow all file
				; modes except BINARY
	CALL	B$DEVOPN 	;Initialize FDB, SI has addr of FDB
	JCXZ	NO_BUFFER	; brif no buffer allocated
	MOV	[SI].FD_VRECL,CX ; save buffer size in FDB
NO_BUFFER:			
	OR	[SI].FD_FLAGS,FL_NEOF ;not at eof
	MOV	[DI].CD_CMFDB,SI ;save FDB pointer in DCB
	MOV	[DI].CD_CMEVT,0 ;init event signal counter
	TEST	[DI].CD_CMFLG,CF_CMBIN
	JZ	CMOPNX		;branch if user wants ASCII mode
	OR	[SI].FD_FLAGS,FL_BIN ; indicate BINARY mode
CMOPNX:
	RET

ERCIFN:
	JMP	B$ERR_BFN	;Bad File Name
ERCDNA:
	JMP	B$ERR_DNA	;device unavailable

;***
; ParseOpt - parse communications option string
;
; Purpose:
;	[Rewritten as part of revision 6].
;	To parse the communication option string and set the
;	appropriate values in the device control block (DCB) for
;	the specified device.
; Inputs:
;	SI = pointer to start of option string.
;	DI = pointer to device control block (DCB).
; Outputs:
;	None.
; Modifies:
;	AX, BX, CX, DX.
; Exceptions:
;	B$ERR_BFN - bad file name error if option string syntax error.
;******************************************************************************

ParseOpt:

;	Parse the first field as a numeric field for the baud rate.

	MOV	[DI].CD_BAUDR,300 ;set the default baud rate
	CALL	GetOptVal	;get the numeric value in DX
	JC	ParseBaudDone	;if null field, then use default
	MOV	[DI].CD_BAUDR,DX ;set the baud rate to the value read
ParseBaudDone:

;	Parse the second field as one letter for the parity type.
;	None(N)=0, Odd(O)=1, Even(E)=2, Mark(M)=3, and Space(S)=4.

	MOV	[DI].CD_PARIT,2	;set the default parity as even
	CALL	GetOptChar	;read the next character in AL
	JC	ParseParDone	;if null field, then use default

	MOV	CX,5		;five parity type to test
	XOR	BX,BX		;initialize the table index
ParseParLoop:
	CMP	AL,CS:ParityTable[BX] ;test field against parity types
	JE	ParseParFound	;if found, then jump to set it
	INC	BX		;increment index to next table entry
	LOOP	ParseParLoop	;loop until last type is tested
ParseError:
	JMP	B$ERR_BFN	;jump to report error in option string

ParityTable	DB	"NOEMS"	;available parity types in order

ParseParFound:
	MOV	[DI].CD_PARIT,BL ;put index as the parity type

	CALL	GetOptChar	;read next character looking for terminator
	JNC	ParseError	;if not terminator, then error
ParseParDone:

;	Parse the third field as a numeric value for the data
;	length (valid range is 5 to 8).

	MOV	[DI].CD_BYTSZ,7 ;default data length is 7 bits
	CALL	GetOptVal	;get the numeric value in DX
	JC	ParseSizeDone	;if null, then jump to use default

	CMP	DX,5		;test lower bound of legal range
	JB	ParseError	;if less, then error
	CMP	DX,8		;test upper bound of legal range
	JA	ParseError	;if more, then error
	MOV	[DI].CD_BYTSZ,DL ;set the size field with the value read
ParseSizeDone:

;	Parse the fourth field as the number of stop bits.  Legal
;	values are 1, 1.5, and 2.  Values are read as characters,
;	not as a numeric value (no leading zeroes).  If no value
;	is given, the default value is:
;		1 stop bit    - 0 - if over 110 baud
;		1.5 stop bits - 1 - if 110 or less baud and 5 bit data length
;		2 stop bits   - 2 - if 110 or less baud and 6-8 bit data length

	XOR	DX,DX		;assume 1 stop bit
	CMP	[DI].CD_BAUDR,110 ;test computed baud rate
	JA	ParseStopDef	;if over 110 baud, jump to set default
	INC	DX		;now assume 1.5 stop bits
	CMP	[DI].CD_BYTSZ,5	;test if 5 bit data length
	JE	ParseStopDef	;if 5 bit data, set default to 1.5 stop bits
	INC	DX		;6-8 bit data, set default to 2 stop bits
ParseStopDef:

	CALL	GetOptChar	;get the first character in field
	JC	ParseStopSet	;if null, jump to use default value in DL
	MOV	DL,AL		;move the character read
	SUB	DL,"1"		;map "1" to 0 and "2" to 1
	CMP	DL,1		;test for valid range (0 to 1)
	JA	ParseError	;if not in range, then error
	SHL	DL,1		;shift so values are 0(1 bit) and 2(2 bits)
	JNZ	ParseStopTerm	;if 2 bits, then jump to test for termination
	CALL	GetOptChar	;get the next char - either "." or terminator
	JC	ParseStopSet	;if terminator, then done - jump
	MOV	AH,AL		;move character for double test
	CALL	GetOptChar	;get next character - should be "5"

	CMP	AX,"5." 	;*WRONG* test if last two characters of "1.5"
	JNE	ParseError	;if not, then syntax error
	INC	DL		;make value 1 for 1.5 stop bits
ParseStopTerm:
	CALL	GetOptChar	;get the terminator character
	JNC	ParseError	;if not, then syntax error
ParseStopSet:
	MOV	[DI].CD_STOPB,DL ;set the stop bit value

;	The fifth and successive fields contain the order-independent
;	parameters, which are identified by their leading characters.
;	These parameters are:
;		RS  - turn off request-to-send
;		OPn - set open timeout to n milliseconds
;		DSn - set data-set-ready timeout to n milliseconds
;		CSn - set clear-to-send timeout to n milliseconds
;		CDn - set carrier-detect timeout to n milliseconds
;		RBn - set size of receive buffer in bytes
;		TBn - set size of transmit buffer in bytes
;		LF  - send line-feed after carriage-return at line end
;		BIN - send data without conversion
;		ASC - send data with conversion
;		PE  - enable reporting of parity errors on received data

	XOR	AX,AX		;clear register for setting values
	MOV	[DI].CD_CMFLG,CF_CMBIN ;clear all flags except for BIN
	MOV	[DI].CD_RLSTO,AX ;set carrier-detect timeout to zero
	MOV	[DI].CD_CTSTO,1000 ;set clear-to-send timeout to 1 second

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -