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

📄 gwcom.asm

📁 DOS 6.22 的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:

	RET			;near return to caller

ComAllocDNAErr:
	JMP	B$ERR_DNA	;give DNA error for /C:0 for interpreter compat


ComAllocOMErrT:
	MOV	AX,[DI].CD_RXSEG ;get segement allocated for the receive queue
	CALL	B$FHHighDealloc ;and deallocate it before giving error
ComAllocOMErrR:			
	JMP	B$ERR_OM_FH	;give OM error if couldn't allocate buffer

B$ComAlloc ENDP		

;***
;B$ComDealloc - Deallocate memory for a communications queue
;
;Purpose:
;	Deallocate the blocks of memory used as a communications queue.
;	The queues to be deallocated are specified by passing the DBC of
;	the communications device.  This device must have queues
;	allocated to it (with B$ComAlloc) otherwise there is a possibility
;	of corrupting memory.
;
;	For OS/2, this routine will also deallocate the stack segment for
;	the thread.
;
;Entry:
;	DI = communications device control block (DCB)
;
;Exit:
;	None.
;
;Uses:
;	Per Convention.
;
;Preserves:
;	AX, BX, CX, DX
;
;Exceptions:
;	May generate B$ERR_MEM or B$ERR_FHC if memory has been
;	corrupted or the segment descriptors in the FDB have been
;	modified.
;******************************************************************************

	PUBLIC	B$ComDealloc	

B$ComDealloc PROC NEAR		

;	Deallocate the block defined in the comm DCB.

	PUSH	AX		;save the register


	MOV	AX,[DI].CD_RXSEG ;get the segment of the block
	CALL	B$FHHighDealloc ;deallocate the segment
	MOV	AX,[DI].CD_TXSEG ;get the segment of the block
	CALL	B$FHHighDealloc ;deallocate the segment


	POP	AX		;restore the register
	RET			;near return to caller

B$ComDealloc ENDP		

;***
; B$ComPreChain - prepare for DOS 5 chaining
; Purpose:
;	Added as part of revision [16].
;	Since DOS 5 CHAIN (with RTM) starts a new process, the current
;	emptier/filler threads must be terminated to be restarted later
;	in the new process itself.  Also, since the receive and transmit
;	buffers are in far memory, new selectors must be mapped using
;	DOSGIVESEG and provided to the new process.
;
; Inputs:
;	CX = pid of the new process
; Outputs:
;	Com buffer selectors are mapped.
; Modifies:
;	None.
; Exceptions:
;	B$ERR_OM - if mapping if selectors fail.
;******************************************************************************


;***
; B$ComPostChain - finish up after DOS 5 chaining
;
; Purpose:
;	Added as part of revision [16].
;	After the chaining is complete, reenable the thread for each
;	active device.
; Inputs:
;	None.
; Outputs:
;	None.
; Modifies:
;	None.
; Exceptions:
;	None.
;******************************************************************************


	SUBTTL	-  EOF, LOC, LOF etc (std file functions)

;COM_EOF - test for End-Of-File on device.
; Entry - SI points to File-Data-Block.
;	  [DI] = device offset (2=COMD, 4=SCRN, etc.)
; Exit	- [AX] = -1 if EOF, 0 if not EOF [1]

; This EOF function will hang waiting for input, but
; presumably, user wants device to look like sequential file, not
; a dynamic COM-I/O device if he is using EOF function.
; EOF(binary_file) is always false.

COM_EOF:
	TEST	[SI].FD_FLAGS,FL_BIN ; binary file?
	JNZ	bineof		;branch if not ascii file
	XOR	BX,BX		;assume no EOF
	CALL	INCHSI		;[AL]=next byte from COM device
	JB	YCMEOF		;branch if next char = EOF
	CALL	COM_BAKC	;put this back in queue
	INC	BX		;BX=0,	end-of-file is false
YCMEOF: DEC	BX		;BX=-1, end-of-file is true
	MOV	AX,BX		; result in AX
	RET

;   In BINARY mode, GW-BASIC EOF is compatible with IBM-PC Basic
;   That is, EOF is true when no data is in input queue.

BINEOF:
	push	dx		;5.40
	push	ax
	call	GetComUnitID	;AX = CD_DEVID in DCB
	mov	ah,al		;AH = CD_DEVID in DCB
	CALL	B$STACOM 	;[DX]=number of bytes in input queue
	call	ckcmer		; check for com error
	mov	bx,dx
	pop	ax
	pop	dx		;5.40
	OR	BX,BX
	JZ	YCMEOF		;branch if input queue is empty
	XOR	AX,AX		; return with [AX]=0 (false)
	RET			; AX=-1 if end-of-file is true

;INCHSI - get next byte from file SI (CTL Z = end-of-file)
; Exit	- Carry set if EOF, else [AL]=byte.
;	  All other regs preserved

INCHSI:
	TEST	[SI].FD_FLAGS,FL_NEOF
	JZ	INCEOF		;branch if EOF already reached
	TEST	[SI].FD_FLAGS,FL_BKC
	JNZ	GETBKC		;branch if char backed up
	CALL	COM_SINP	;[AL]=next input from file
	JB	INCEOF		;branch if device detected EOF
	RET

GETBKC: AND	[SI].FD_FLAGS,NOT FL_BKC ;Flag char as no longer backed up
	MOV	AL,[SI].FD_BAKC	;Get backup char
	CLC			;Make sure EOF isnt set
	RET

INCEOF: AND	[SI].FD_FLAGS,NOT FL_BKC ;Tell the world no char backed up
	STC			;Set carry to indicate EOF
	RET

;COM_BAKC - backup sequential input file
;	    original name: BCHRSI
;   Entry - [AL] = char to be backed up
;	    [SI] points to FDB of file to be backed up

COM_BAKC:
	MOV	[SI].FD_BAKC,AL
	OR	[SI].FD_FLAGS,FL_BKC ;set flag indicating char backed up
	RET

;B$COMLOC -- entry point to B$STACOM for $polcom in gwaevt
;entry: same as B$STACOM
;exit:	same as B$STACOM

	PUBLIC	B$COMLOC
B$COMLOC:
	JMP	B$STACOM	

;COM_LOC - Number of Bytes in input buffer for device.
; Entry - SI points to File-Data-Block.
;	  DI = device offset
; Exit	- [DX|AX] has I4 result
;	  uses DI

COM_LOC:
	CALL	GetComUnitID	;AL=Unit ID
	MOV	AH,AL
	CALL	B$STACOM 	;[DX]=number of bytes in input buffer
	CALL	CKCMER		;Check for Com Error
	TEST	[SI].FD_FLAGS,FL_BKC
	JZ	CMLOCX		;branch if char not backed up
	INC	DX
CMLOCX:
	MOV	AX,DX		; result in [DX|AX]
	JMP	SHORT DBLEX

;COM_LOF - number of bytes free in OUTPUT buffer.
; Entry - SI points to File-Data-Block.
;	  [DI] = device offset (2=COMD, 4=SCRN, etc.)
; Exit	- [DX|AX] has I4 result
;	  uses DI
COM_LOF:
	CALL	GetComUnitID	;AL=Unit ID
	MOV	AH,AL
	CALL	B$STACOM 	;Result in CX
	CALL	CKCMER		;Check for Com error
	MOV	AX,CX		; Put result in DX, now Zero the Regs:
DBLEX:
	XOR	DX,DX		; DX=0
	RET			;return result in FAC

;COM_CLOSE - perform any device dependent close functions.
; Entry - SI points to File-Data-Block.
;	  [DI] = device offset (2=COMD, 4=SCRN, etc.)
; Exit	- All registers preserved.
;	  This routine releases the fdata-block associated with this file.

DbPub	<COM_CLOSE>		
COM_CLOSE:
DbAssertRelB	<[b$COFlag]>,E,0,DV_TEXT,<b$COFlag non-zero in COM_CLOSE> ;
	CALL	GetComDCB	;DI points to device control block
	TEST	[SI].FD_FLAGS,FL_BIN ; binary file?
	JNZ	COMCLX		; Branch if BINARY file mode
	CMP	[SI].FD_MODE,MD_SQI
	JE	COMCLX		;don't send EOF if input mode
	MOV	AL,EOFCHR	;else send CTL-Z indicating EOF
	CALL	CMROUT
COMCLX:
	MOV	AH,[DI].CD_DEVID ;get device id
	PUSH	CX		; must preserve CX for dispatch count
	XOR	CX,CX		; CX = 0 to RESET DTR and RTS (DOS 3 only)
	CALL	B$TRMCOM 	;close device
	POP	CX		; Restore CX = dispatch count
	CALL	B$ComDealloc	;[2]deallocate the comm buffer
	MOV	[DI].CD_CMFDB,0 ;mark device as not-in-use
	CALL	B$LHDALC_CPCT	; Deallocate FDB and compact local heap
	JMP	CKCMER		; check for B$TRMCOM error and return


;COM_WIDTH - set file width
; Entry - SI points to File-Data-Block.
;	  [DX] = new device width
;	  [DI] = device offset (2=COMD, 4=SCRN, etc.)
; Exit	- All registers preserved

COM_WIDTH:
	MOV	[SI].FD_WIDTH,DL ;set DCB value to be effective now
	RET


;*** 
;COM_DWID - Set device width.  Added with [20].
;
;Purpose:
;
;Entry:
;	[DL] = new device width
;	[DI] = device offset
;Exit:
;	None
;Uses:
;	Per convention
;Exceptions:
;	None
;
;******************************************************************************
cProc	COM_DWID,<NEAR>,<DI>
cBegin
	CALL	GetComDCB	; get DCB in DI
	MOV	[DI].CD_CMWID,DL ; update DCB value
cEnd


;***
;COM_RANDIO -- low level routine to access comm for GET/PUT
;
;Purpose:
; This routine reads from/writes to a comm port a record.
;
;Entry:
;	[AL]		= flags
;			  Bit 0: 1 if PUT, else GET
;			  BIT 1: 1 if explicit record number specified
;			  BIT 2: 1 if record variable specified
;	[BX]		= record length to be written
;	[CX|DX] 	= user specified record number if GET/PUT (This number
;			  is used to override the length to be read/written)
;	[DI]		= Device Offset
;	[SI]		= *FDB
;	[b$RECPTR]	= Pointer to the data to be written
;
;Exit:
;	[AX]		= number of bytes actual read/write
;	one buffer is filled/flushed
;Uses:
;	Per convention
;
;Exceptions:
;	B$ERR_FC  -- illegal function call
;
;*******************************************************************************
cProc	COM_RANDIO,NEAR,ES	
cBegin				
	TEST	AL,RelFlg	; See if record specified
	JNZ	CRAND_5 	; Jump if record specified
	MOV	DX,BX		; [DX] = length to be read/written
	JMP	SHORT CRAND_20	; Go perform operation

CRAND_5:			; Record specified
	JCXZ	CRAND_15	; Jump if rec num < 64k (valid)
ERRFC:				
	JMP	B$ERR_FC	; Record number too big
CRAND_15:			
	CMP	BX,DX		; Record number must be less than buffer
	JC	ERRFC		; Jump if record number exceeds buff size

; [BX] = size of the buffer (size to clear for GET)
; [DX] = number of characters to actually deal with

CRAND_20:			
	MOV	CX,BX		; [CX] = size of buffer
	LES	BX,[b$RECPTR]	; [ES:BX] = pointer to buffer
	TEST	AL,PutFlg	; See if put or get
	JNZ	CRAND_30	; Jump if PUT

	PUSH	DI		; Save dispatch offset
	MOV	DI,BX		; [ES:DI] = pointer to buffer
	MOV	AL," "		; [AL] = a space to place
	REP	STOSB		; Fill buffer
	POP	DI		; [DI] = dispatch offset

	MOV	CX,DX		; [CX] = number of characters to get
CRAND_25:			
	PUSH	DI		; Save dispatch offset
	CALL	COM_SINP	; [AL] = next byte from comm port
	POP	DI		; [DI] = dispatch offset
	MOV	ES:[BX],AL	; Place into buffer
	INC	BX		; Move on
	LOOP	CRAND_25	; For all characters desired
	JMP	SHORT CRAND_90	; exit

CRAND_30:			; Put
	MOV	CX,DX		;get number of characters to output
	CALL	GetComDCB	; [DI] = DCB pointer
CRAND_35:			
	MOV	AL,ES:[BX]	; [AL]=next byte from buffer
	CALL	CMROUT		; output to com port
	INC	BX		; bump buffer pointer
	LOOP	CRAND_35	; For all characters desired

CRAND_90:			
	XCHG	AX,DX		; return count in AX

cEnd


;COM_SINP - Sequential Input.
; Entry - SI points to File-Data-Block.
;	  [DI] = device offset (2=COMD, 4=SCRN, etc.)
; Exit	- [AL] = next byte from file,
;	  carry set if EOF.
;	  All other registers preserved

COM_SINP:
	TEST	[SI].FD_FLAGS,FL_BKC ;Is a char backed up?
	JZ	CSWAIT		;No - go get one
	MOV	AL,[SI].FD_BAKC	;Yes get ch from backup
	AND	[SI].FD_FLAGS,NOT FL_BKC ;char is no longer backed up
	JMP	SHORT CMNEOF	;indicate no eof and return

⌨️ 快捷键说明

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