📄 gwcom.asm
字号:
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 + -