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

📄 gwcom.asm

📁 DOS 6.22 的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	MOV	[DI].CD_DSRTO,1000 ;set data-set-ready timeout to 1 second
	MOV	[DI].CD_RXSIZ,AX ;clear receive buffer size for default
	MOV	[DI].CD_TXSIZ,AX ;clear transmit buffer size for default

;	The first character of each parameter is read.  If a null field,
;	it is ignored.  If at the option string end, then return.

ParseLoop:
	CALL	GetOptChar	;read the first character in AL
	JNC	ParseNext	;if not a separator, then start processing
	JNZ	ParseLoop	;if comma, then just ignore it
	JMP	ParseEnd	;else process end of statement

;	Test for valid prefix on parameter.  To reduce code size, read the
;	second character and use both for testing.

ParseNext:
	MOV	AH,AL		;move first character
	CALL	GetOptChar	;first character in AH, second in AL

;	First, test for "RS".  If so, then set RS flag and set default
;	CSn value to zero.

	CMP	AX,"RS"		;test if RS
	JNE	ParseOP		;if not, try OP next
	OR	[DI].CD_CMFLG,CF_CMRTS ;set the RS flag in the DCB
	TEST	[DI].CD_CMFLG,CF_CMCTS ;test if CS value is still default
	JNZ	ParseTerm	;test for termination after parameter
	MOV	[DI].CD_CTSTO,0	;set the CS timeout value to 0 (disable)

;	For parameters that do not have a numeric argument that is
;	processed with GetOptVal, the character after the parameter
;	must be a terminator (comma or end-of-string).

ParseTerm:
	CALL	GetOptChar	;get what should be terminator
	JC	ParseLoop	;if so, then loop for the next parameter
ParseTermErr:
	JMP	B$ERR_BFN	;jump to report error in option string

;	Second, test for "OP".  If so, then read the following numeric
;	value and put it in the DCB and set the flag.

ParseOP:
	CMP	AX,"OP"		;test for OP
	JNE	ParseDS		;if not, then test for DS
	CALL	GetOptVal	;get numeric value in DX
	JNC	ParseOPNoDef	;if numeric value specified, then jump
	MOV	DX,10000D	;otherwise set to 10 seconds
ParseOPNoDef:
	MOV	[DI].CD_OPNTO,DX ;put value in DCB
	OR	[DI].CD_CMFLG,CF_CMOPN ;set flag for OP parameter given
	JMP	SHORT ParseLoop	;jump to process next parameter

;	Third, test for "DS".  If so, then read the following numeric
;	value and put it in the DCB.

ParseDS:
	CMP	AX,"DS"		;test for DS
	JNE	ParseCD		;if not, then test for CD
	CALL	GetOptVal	;get numeric value in DX
	MOV	[DI].CD_DSRTO,DX ;put value in DCB
	JMP	SHORT ParseLoop	;jump to process next parameter

;	Fourth, test for "CD".  If so, then read the following numeric
;	value and put it in the DCB.

ParseCD:
	CMP	AX,"CD"		;test for CD
	JNE	ParseCS		;if not, then test for CS
	CALL	GetOptVal	;get numeric value in DX
	MOV	[DI].CD_RLSTO,DX ;put value in DCB
	JMP	SHORT ParseLoop	;jump to process next parameter

;	Fifth, test for "CS".  If so, then read the following numeric
;	value and put it in the DCB.
	
ParseCS:
	CMP	AX,"CS"		;test for CS
	JNE	ParseRB		;if not, then test for RB
	CALL	GetOptVal	;get numeric value in DX
	MOV	[DI].CD_CTSTO,DX ;put value in DCB
	OR	[DI].CD_CMFLG,CF_CMCTS ;set flag for nondefault CS timeout
	JMP	SHORT ParseLoop	;jump to process next parameter

;	Sixth, test for "RB".  If so, then read the following numeric
;	value and put it in the DCB.

ParseRB:
	CMP	AX,"RB"		;test for RB
	JNE	ParseTB		;if not, then test for TB
	CALL	GetOptVal	;get numeric value in DX
	MOV	[DI].CD_RXSIZ,DX ;put value in DCB
	JMP	SHORT ParseLoop	;jump to process next parameter

;	Seventh, test for "TB".  If so, then read the following numeric
;	value and put it in the DCB.

ParseTB:
	CMP	AX,"TB"		;test for TB
	JNE	ParseLF		;if not, then test for LF
	CALL	GetOptVal	;get numeric value in DX
	MOV	[DI].CD_TXSIZ,DX ;put value in DCB
	JMP	ParseLoop	;jump to process next parameter

;	Eighth, test for "LF".  If so, then set the flag in the DCB.

ParseLF:
	CMP	AX,"LF"		;test for LF
	JNE	ParseBIN	;if not, then test for BIN
	OR	[DI].CD_CMFLG,CF_CMCLF ;set the LF flag
	JMP	SHORT ParseTerm	;jump to check for terminator

;	Ninth, test for "BIN".  If so, then set the flag in the DCB.

ParseBIN:
	CMP	AX,"BI"		;test for BI
	JNE	ParseASC	;if not, then test for ASC
	CALL	GetOptChar	;get the third character
	CMP	AL,"N"		;test if parameter was BIN
	JNE	ParseTermErr	;if not, then error
ParseCOD:
	TEST	[DI].CD_CMFLG,CF_CMCOD ;test if ASC or BIN specified before
	JNZ	ParseTermErr	;if so, then error
	OR	[DI].CD_CMFLG,CF_CMCOD ;set the flag for ASC or BIN specified
	JMP	ParseTerm	;jump to test for terminator

;	Tenth, test for "ASC".  If so, then clear the flag in the DCB.

ParseASC:
	CMP	AX,"AS"		;test for AS
	JNE	ParsePE		;if not, then test for PE
	CALL	GetOptChar	;get the third character
	CMP	AL,"C"		;test if parameter was ASC
	JNE	ParseTermErrJmp	;if not, then error
	AND	[DI].CD_CMFLG,NOT CF_CMBIN ;clear the binary mode flag
	JMP	SHORT ParseCOD	;jump to check CF_CMCOD in DCB

ParseTermErrJmp:
	JMP	ParseTermErr	;short jump to process error

;	Finally, test for "PE".  If so, then set the flag in the DCB.

ParsePE:
	CMP	AX,"PE"		;test for PE
	JNE	ParseTermErrJmp	;if not, then unknown parameter - error
	OR	[DI].CD_CMFLG,CF_CMPEN ;set the flag PE specified
	JMP	ParseTerm	;jump to test for terminator

;	The end of the statement has been reached.  If not specified,
;	compute the open timeout value to be ten times the maximum of the
;	other timeouts, with a maximum value of 64K-1 milliseconds.

ParseEnd:			
	TEST	[DI].CD_CMFLG,CF_CMOPN ;test if nondefault OP timeout
	JNZ	ParseRet	;if so, then use the one specified
	MOV	AX,[DI].CD_RLSTO ;get the CD timeout value
	CMP	AX,[DI].CD_DSRTO ;test against the DS timeout value
	JA	ParseKeep1	;jump to keep greater value in AX
	MOV	AX,[DI].CD_DSRTO ;else update the maximum value
ParseKeep1:			
	MOV	CX,0FFFFH	;assume maximum value
	MOV	DX,10		;factor to multiply maximum time
	MUL	DX		;compute OP timeout in DX:AX
	JC	ParseSetOP	;if over 64K-1, then jump to set max
	MOV	CX,AX		;set the product
ParseSetOP:			
	MOV	[DI].CD_OPNTO,CX ;set the OP timeout value
ParseRet:			
	RET			;if statement end, then finished, so return


;***
; GetOptChar - get a character in the option string
;
; Purpose:
;	[Rewritten as part of revision 6].
;	The next character in the option string is read into AL.
;	If lower case, it is mapped to upper case and the carry and
;	zero flags are set accordingly.  Blank and tab characters
;	are ignored.
; Input:
;	SI = pointer to next character in the option string.
; Outputs:
;	SI = pointer to the following character (except for string end).
;	AL = character (mapped if lower case).
;	CF set and ZF set = end of string
;	CF set and ZF clear = comma character
;	CF clear and ZF clear = not comma or end of string
; Modifies:
;	None.
; Exceptions:
;	None.
;*****************************************************************************

GetOptChar:
	LODSB			;get the next character from the string
	CMP	AL," "		;test if blank character
	JE	GetOptChar	;if so, then ignore it
	CMP	AL,ASCHT	;test if tab character
	JE	GetOptChar	;if so, then also ignore it
	CMP	AL,","		;test if comma
	JE	GetOptStc	;if so, then return with CF set and ZF clear
	CMP	AL,"a"		;test if character is lower case
	JB	GetOptNoMap	;if not, then skip the mapping
	ADD	AL,"A"-"a"	;map lower case letter to upper
GetOptNoMap:
	OR	AL,AL		;test if at the end of the string
	JNZ	GetOptRet	;if not end, then return with CF and ZF clear
	DEC	SI		;backup pointer to the statement end
	OR	AL,AL		;clear ZF again for exit condition
GetOptStc:
	STC			;set carry for end-of-statement or comma
GetOptRet:
	RET			;near return to caller

;***
; GetOptVal - get value from option string
;
; Purpose:
;	[Rewritten as part of revision 6].
;	To read the option string for characters to be interpreted
;	as decimal digits.  A value from these digits is computed
;	and returned.  This routine then checks for a proper terminating
;	character (either a comma or end-of-string) after the value.
;	If no terminator, then an error is reported.
; Inputs:
;	SI = pointer to option string at value.
; Outputs:
;	SI = pointer to option string after the terminator.
;	DX = computed value.
;	CY set = null value (first character terminator).
;	   clear = nonnull value.
; Modifies:
;	AX.
; Exceptions:
;	B$ERR_BFN - bad file name if improper terminator.
;*****************************************************************************

GetOptVal:
	PUSH	BX		;save register
	XOR	DX,DX		;initialize result
	CALL	GetOptChar	;get the first character of the value
	JC	GetOptValRet	;return with CY set for null value
	DEC	SI		;back up over first character read
GetOptValLoop:
	CALL	GetOptChar	;get option string character in AL
	CMC			;complement so CY clear for terminator
	JNC	GetOptValRet	;return with CY clear for nonull value
	SUB	AL,"0"		;subtract bias for decimal digit
	CMP	AL,9		;test if digit or not
	JA	GetOptValErr	;if not digit or terminator, then error
	CBW			;zero AH for word value
	SHL	DX,1		;present result * 2
	JC	GetOptValErr	;jump if overflow error
	MOV	BX,DX		;save result * 2
	SHL	DX,1		;present result * 4
	JC	GetOptValErr	;jump if overflow error
	SHL	DX,1		;present result * 8
	JC	GetOptValErr	;jump if overflow error
	ADD	DX,BX		;present result * 10
	JC	GetOptValErr	;jump if overflow error
	ADD	DX,AX		;add in new digit - new value
	JNC	GetOptValLoop	;if no overflow, then loop for next
GetOptValErr:
	JMP	B$ERR_BFN	;if error, then bad file name
GetOptValRet:
	POP	BX		;restore register
	RET			;near return to caller

;
;Written as part of revision [6]
;
;***
;B$ComAlloc - Allocate memory for a communications device
;
;Purpose:
;	From high memory, allocate two blocks for use as communications
;	queues, one for the receive queue and the other for the transmit
;	queue.	The size of the two queues is passed into this procedure
;	as an arguement.
;
;	If the size specified for the receive queue is 0, then the size
;	given on the command line with the /C:xxx option is used.  If this
;	value is -1 (not specified), then the queue will be cbComBuf bytes
;	long.  If the size specified for the transmit queue is 0, then
;	it will be cbComBuf bytes long.
;
;	On exit, the DCB of the communications device that was passed
;	in as a parameter will have the segment which contains the
;	receive queue and the transmit queue.  The queues will be the
;	first (and only) things in the segments.  The fields of the
;	DCB are defined in comdcb.inc.
;
;	For OS/2, this routine will also allocate a 2K-byte block for the
;	stack of the thread.
;
;Entry:
;	DI = communications device control block (DCB)
;	[DI].CD_RXSIZ = size of the receive queue in bytes
;	[DI].CD_TXSIZ = size of the transmit queue in bytes
;
;Exit:
;	[DI].CD_RXSEG = segment of memory allocated for the receive queue
;	[DI].CD_TXSEG = segment of memory allocated for the transmit queue
;	[DI].CD_SPSIZ = size of the thread stack in bytes (2048+slop)
;	[DI].CD_SPSEG = segment of memory allocated for the thread stack
;
;Uses:
;	Per convention.
;
;Exceptions:
;	B$ERR_DNA - device not available if /C:0 for compatibility
;		     This error will be given if the option's value is
;		     needed or not.
;	B$ERR_OM  - out of memory if allocation failed for any reason.
;****************************************************************************

	PUBLIC	B$ComAlloc	

B$ComAlloc PROC NEAR		

;	Get the C parameter value for comm buffer size.

	MOV	AX,b$cbComBuffer ;get /C:nnnn value saved from command line

;	If buffer size is zero, then error.

	OR	AX,AX		;test if zero buffer size
	JZ	ComAllocDNAErr	;if so, then give "device not available" error

;	Compute the size of the receive queue.  If [DI].CD_RXSIZ is
;	nonzero, use the size specified in the RB[n] parameter.

	MOV	DX,[DI].CD_RXSIZ ;get the receive buffer size
	OR	DX,DX		;test if specified
	JNZ	ComAllocRB	;if so, then use it

;	Use size in AX from command line, except for -1 where the
;	default is cbComBuf bytes.

	MOV	DX,cbComBuf	;default size for receive buffer
	CMP	AX,-1		;test if -1 for default
	JE	ComAllocRBSet	;if default, use cbComBuf bytes
	MOV	DX,AX		;move size from command line for use
ComAllocRBSet:
	MOV	[DI].CD_RXSIZ,DX ;set the block size

;	Allocate the receive queue and set buffer segment in DCB.

ComAllocRB:
	MOV	AX,DX		;move the size into AX
	XOR	DX,DX		;size in bytes now in DX:AX
	CALL	B$FHHighAlloc	;allocate the comm buffer with segment in CX
	JCXZ	ComAllocOMErrR	;out of memory if couldn't allocate buffer
	MOV	[DI].CD_RXSEG,CX ;[8]set the DCB segment

;	Compute the size of the transmit queue.  If [DI].CD_TXSIZ is
;	nonzero, use the size specified in the TB[n] parameter.

	MOV	AX,[DI].CD_TXSIZ ;get the transmit buffer size
	OR	AX,AX		;test if specified
	JNZ	ComAllocTB	;if so, then use it

;	If not specified, use the size of cbComBuf bytes.

	MOV	AX,cbComBuf	 ;default size for transmit buffer
	MOV	[DI].CD_TXSIZ,AX ;set the default size of the buffer

;	Allocate the transmit queue and set buffer segment in DCB.

ComAllocTB:
	XOR	DX,DX		;size in bytes now in DX:AX
	CALL	B$FHHighAlloc	;allocate the comm buffer with segment in CX
	JCXZ	ComAllocOMErrT	;out of memory allocation failed
	MOV	[DI].CD_TXSEG,CX ;[8]set the DCB segment

;	Allocate the stack for the thread and set segment in DCB.

⌨️ 快捷键说明

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