home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Phoenix CD 2.0
/
Phoenix_CD.cdr
/
01e
/
msk230s1.zip
/
MSSRCV.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-02-12
|
33KB
|
651 lines
NAME mssrcv
; File MSSRCV.ASM
; Edit history
; Last edit: 7 Jan 1988
; 7 Jan 1988 Check for Control-E condition before sending a NAK. [jrd]
; 1 Jan 1988 version 2.30
; 26 Dec 1987 Clean out unused pack.oldtry, etc., clean up. [jrd]
; 6 Dec 1987 Flush last disk buffer when aborting a transfer. [jrd]
; 8 Oct 1987 Ensure error pkts use 1 byte chksum at init stage. [jrd]
; 27 Aug 1987 Add tests for receiving to screen for error reports [jrd]
; 23 July 1987 Add buffer clear after opening new output file. [jrd]
; 7 June 1987 Add DOS errlev return of 2 for failure to receive. [jrd]
; 7 May 1987 Correct placement of begtim and endtim statistics calls. [jrd]
; 19 Oct 1986 Fix Rinit to use 1 byte checksums on Naks to S packets.
; 1 Oct 1986 Version 2.29a
; 17 Sept 1986 Fix file not being deleted when transfer fails. [jrd]
; 14 August 1986 Allow changing EOL characters.
; 9 August 1986 Allow Control-X/Z exit while getting 'S' packet. [jrd]
; 27 July 1986 Clear file opened flag to prevent unwanted closing of stdin.
; 16 June 1986 Add clearing of "flags.getflg" under read0: to prevent missing
; initial packet read for REC commands. [jrd]
; 26 May 1986 Revise code to permit serial display. [jrd]
; [2.29] code frozen on 6 May 1986 [jrd]
public read12, read2, rin21, rfile3, read, updrtr, nak, rrinit
include mssdef.h
datas segment public 'datas'
extrn data:byte, bufpnt:word, chrcnt:word, curchk:byte
extrn comand:byte, flags:byte, pack:byte, trans:byte, dtrans:byte
extrn diskio:byte, locfil:byte, maxtry:byte, imxtry:byte
extrn fsta:word, errlev:byte
ermes7 db '?Unable to receive initiate-packet$'
ermes8 db '?Unable to receive file name$'
ermes9 db '?Unable to receive end of file$'
erms10 db '?Unable to receive data$'
infms1 db cr,' Receiving: In progress',cr,lf,'$'
infms3 db 'Completed',cr,lf,'$'
infms4 db 'Failed',cr,lf,'$'
infms6 db 'Interrupted',cr,lf,'$'
filhlp2 db ' Local path or filename or carriage return$'
ender db bell,bell,'$'
crlf db cr,lf,'$'
temp dw 0
filopn db 0 ; Says if disk file is open.
datas ends
code segment public 'code'
extrn gofil:near, outbuf:near, comnd:near
extrn spack:near, rpack:near, serini:near, serrst:near
extrn spar:near, rpar:near, init:near, cxmsg:near
extrn error:near, ptchr:near, erpos:near, rtpos:near
extrn stpos:near, rprpos:near, nppos:near, nout:near
extrn dodec:near, doenc:near, errpack:near, intmsg:near
extrn send11:near, clrmod:near, ihostr:near
extrn begtim:near, endtim:near, pktsize:near
assume cs:code, ds:datas
; Update retry count and fall through to send a NAK.
NAK0: call updrtr ; Update retry count.
nak1: cmp flags.cxzflg,'E' ; Protocol abort sign?
jne nak ; ne = no
ret ; return to do current ('A') state
NAK: mov ax,pack.pktnum ; Get the packet number we're waiting for
mov pack.argblk,ax
mov pack.argbk1,0
add fsta.nakscnt,1 ; count NAKs sent
;;; mov cx,0 ; No data, but this may change.
;;; call doenc ; So call encode.
mov ah,'N' ; NAK that packet.
call spack
jmp abort
nop ; So 'jmp rskp' in SPACK comes here
ret ; Go around again.
updrtr: cmp pack.state,'A' ; Supposed to abort?
je upd0 ; Yes, don't bother with retry count.
inc pack.numrtr ; Increment the number of retries.
cmp flags.xflg,1 ; Writing to screen?
je upd0 ; e = yes, skip this
cmp pack.numrtr,0 ; non-zero item to display?
je upd0 ; nothing to display
call rtpos ; Position cursor.
mov ax,pack.numrtr
call nout ; Write the number of retries.
upd0: ret
; Abort
ABORT PROC NEAR
cmp filopn,0 ; Disk file open?
je abort0 ; e = no so don't close.
cmp flags.xflg,1 ; Writing to the screen?
je abort0 ; Yes, don't close "file".
call outbuf ; flush last buffer to disk, ignore errors.
nop
nop
nop
mov ah,close2 ; DOS 2.0 file close
push bx
mov bx,diskio.handle ; file handle
int dos
pop bx
mov filopn,0 ; say file is no longer open
cmp flags.abfflg,0 ; save file after closing?
je abort0 ; e = yes
push dx
mov dx,offset diskio.string ; get back file name
mov ah,del2 ; delete the file
int dos
pop dx
abort0: mov pack.state,'A' ; Otherwise abort.
mov byte ptr locfil,0 ; clear local filename
or errlev,2 ; set DOS error level
ret
ABORT ENDP
; init variables for read...
rrinit proc near
mov pack.numpkt,0 ; Set the number of packets to zero.
mov pack.numrtr,0 ; Set the number of retries to zero.
mov pack.pktnum,0 ; Set the packet number to zero.
mov pack.numtry,0 ; Set the number of tries to zero.
mov filopn,0 ; say no file opened yet
ret
rrinit endp
; RECEIVE command -- Some code moved to the GET routine
READ PROC NEAR
mov flags.nmoflg,0 ; Override file name from other host?
mov bx,offset filhlp2 ; Text of help message.
mov dx,offset locfil ; local file name string
mov byte ptr locfil,0 ; clear it first
mov ah,cmfile ; allow path names
call comnd
jmp r
cmp ah,0 ; was an override filename given?
je read0 ; e = no
mov flags.nmoflg,1 ; yes, set flag = use this filename.
read0: mov comand.cmrflg,0 ; Reset flag.
mov comand.cmcr,0
mov ah,cmcfm ; Get a confirm.
call comnd
jmp r
mov pack.state,'R' ; Set the state to receive initiate
mov flags.getflg,0 ; Reset flag (not a Get command)
mov flags.xflg,0
call rrinit ; init variables for read
call init ; setup display form
call serini ; Initialize serial port
call ihostr ; initialize the host
mov ax,0 ; tell statistics this was a receive operation
call endtim ; get tod of end of file transfer
call begtim ; start next statistics group
READ12: ; Called by GET & SRVSND, display ok
mov flags.cxzflg,0 ; Reset ^X/^Z flag.
mov ah,trans.chklen ; get desired checksum length
mov curchk,ah ; and remember it here
test flags.remflg,dquiet ; quiet display mode?
jnz read2 ; nz = yes, no printing
cmp flags.destflg,2 ; Receiving to the screen?
je read21 ; e = yes, no formatted display
call stpos
mov ah,prstr ; Be informative.
mov dx,offset infms1
int dos
test flags.remflg,dserial ; serial display mode?
jnz read2 ; nz = yes, skip initial retry display
call rtpos ; Position cursor.
mov ax,pack.numrtr
call nout ; Write the number of retries.
READ2: ; Called by GENERIC server command dispatcher
cmp flags.xflg,1 ; Are we receiving to the screen?
je read21 ; e = skip the screen stuff.
call nppos ; Position cursor for number of packets msg.
mov ax,pack.numpkt
call nout ; Write the number of packets.
read21: mov ah,pack.state ; Get the state.
cmp ah,'D' ; Data receive state?
jne read3
call rdata ; yes, get data packets
jmp read2
read3: cmp ah,'F' ; File receive state?
jne read4
call rfile ; Call receive file.
jmp read2
read4: cmp ah,'R' ; Receive initiate state?
jne read5
call rinit
jmp read2
; Receive Complete state processor
read5: push ax ; save status in ah
xor ax,ax ; tell statistics this is a receive operation
call endtim ; stop file timer
call serrst ; Reset serial port.
mov ah,curchk ; get working checksum
mov trans.chklen,ah ; and restore for next file
mov byte ptr locfil,0 ; clear local filename
pop ax
mov dx,offset infms3 ; Completed message
cmp ah,'C' ; Receive complete state?
je read6 ; e = yes, else receive failed.
mov dx,offset infms4 ; Failed message
or errlev,2 ; set DOS error level
cmp filopn,2 ; file still open?
jne read6 ; ne = no.
push dx
call abort ; close file & maybe delete
pop dx
read6: cmp flags.xflg,0 ; Did we write to the screen?
je read6a ; e = no, so print status.
cmp flags.destflg,2 ; Receiving to screen?
je read6d ; Yes don't reset.
mov flags.xflg,0 ; Reset it.
jmp read6d ; Yes, so just return.
read6a: test flags.remflg,dquiet ; quiet display mode?
jnz read6d ; nz = yes, keep going
cmp flags.destflg,2 ; Receiving to the screen?
je read6d ; e = yes, no formatted display
push dx ; save message pointer
call stpos ; Position cursor.
pop dx
mov ah,prstr
cmp flags.cxzflg,0 ; Completed or interrupted?
je read6b ; Ended normally.
or errlev,2 ; set DOS error level
mov dx,offset infms6 ; Say was interrupted.
read6b: int dos
cmp flags.belflg,0 ; Bell desired?
je read6c ; No.
mov dx,offset ender ; Ring them bells.
int dos
read6c: test flags.remflg,dserial ; serial display?
jnz read6d ; nz = yes
call clrmod ; clear Mode Line
call rprpos ; Put prompt here.
read6d: jmp rskp
READ ENDP
; Receive routines
; Receive init
RINIT PROC NEAR
mov ah,pack.numtry ; Get the number of tries.
cmp ah,imxtry ; Reached the maximum number of tries?
jl rinit2
mov dx,offset ermes7
test flags.remflg,dquiet ; quiet display mode?
jnz rinit1 ; nz = yes. Don't write to screen.
cmp flags.destflg,2 ; Receiving to the screen?
je rinit1 ; e = yes, no formatted display
call erpos ; Position cursor.
mov ah,prstr
int dos ; Print an error message.
rinit1: mov bx,dx
mov ah,trans.chklen
mov curchk,ah ; Store checksum length we want to use.
mov trans.chklen,1 ; Send init checksum is always 1 char.
call errpack ; Send error packet just in case.
mov ah,curchk
mov trans.chklen,ah ; Reset to desired value.
jmp abort ; Change the state to abort.
rinit2: inc ah ; Increment it.
mov pack.numtry,ah ; Save the updated number of tries.
mov ax,pack.argbk2 ; get packet type if here from get
cmp flags.getflg,1 ; Have we already read in the packet?
je rin21a ; Yes, so don't call RPACK.
mov ah,dtrans.seol ; restore default end-of-line char
mov trans.seol,ah
mov ah,trans.chklen
mov curchk,ah ; Save checksum length we want to use.
mov trans.chklen,1 ; Use 1 char for init packet.
call rpack ; Get a packet.
jmp rin22 ; Trashed packet: nak, retry.
call pktsize ; report packet size
push ax
mov ah,curchk
mov trans.chklen,ah ; Reset to desired value.
pop ax
cmp flags.cxzflg,0 ; does the user want out now?
jne rinit4 ; ne = yes, quit
rin21a: cmp ah,'S' ; Is it a send initiate packet?
jne rinit3 ; If not see if its an error.
rin21: mov flags.getflg,0 ; Reset flag.
mov pack.numtry,0 ; Reset the number of tries.
mov ax,pack.argblk ; Returned packet number. (Synchronize them.)
inc ax ; Increment it.
and ax,3FH ; Turn off the two high order bits.
mov pack.pktnum,ax ; Save modulo 64 of the number.
inc pack.numpkt ; Increment the number of packets.
mov ax,pack.argbk1 ; Get the number of arguments received
mov bx,offset data ; Get a pointer to the data
call spar ; Get data into the proper variables
mov bx,offset data ; Get a pointer to our data block
call rpar ; Set up the receive parameters
xchg ah,al
mov ah,0
mov pack.argbk1,ax ; Store returned number of arguments
mov ah,trans.chklen ; Checksum length we'll use.
mov curchk,ah ; Save it.
mov trans.chklen,1 ; Use 1 char for init packet.
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
mov ah,curchk ; Checksum length we'll use.
mov trans.chklen,ah ; Reset to desired value.
mov pack.state,'F' ; Set the state to file send.
ret
rin22: call nak0 ; nak the packet
mov ah,curchk ; and only now change checksum from 1
mov trans.chklen,ah ; Reset to desired value.
ret ; try again
rinit3: cmp ah,'E' ; Is it an error packet?
jne rinit4 ; ne = no
call error ; yes
rinit4: jmp abort
RINIT ENDP
; Receive file
RFILE PROC NEAR
mov dl,maxtry
cmp pack.numtry,dl ; Have we reached the maximum number of tries?
jl rfile1
mov dx,offset ermes8
jmp rcverr ; do error exit
rfile1: inc pack.numtry ; Save the updated number of tries.
call rpack ; Get a packet.
jmp nak0 ; Trashed packet: nak, retry.
call pktsize ; report packet size
cmp ah,'S' ; Is it a send initiate packet?
je rfil10
cmp ah,'I' ; An Initialization packet?
je rfil10 ; e = yes, don't decode it
rfil09: call dodec ; Decode all other incoming packets.
jmp rfile2 ; No, try next type.
rfil10: mov dl,imxtry ; S and I packets
cmp pack.numtry,dl ; Reached the maximum number of tries?
jl rfil12 ; If not proceed.
mov dx,offset ermes7
jmp rcverr ; do error exit
rfil12: mov ax,pack.pktnum ; Get the present packet number.
cmp ax,0 ; Had we wrapped around?
jne rfilx
mov ax,64
rfilx: dec ax ; Decrement.
cmp ax,pack.argblk ; Is the packet's number one less than now?
je rfil13
jmp nak0 ; No, NAK and try again.
rfil13: mov pack.numtry,0 ; Reset the number of tries.
mov bx,offset data ; Get a pointer to our data block.
call rpar ; Set up the parameter information.
xchg ah,al
mov ah,0
mov pack.argbk1,ax ; Save the number of arguments.
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
ret
rfile2: cmp ah,'Z' ; Is it an EOF packet?
jne rfile3 ; No, try next type.
mov dl,maxtry ; Z packets
cmp pack.numtry,dl ; Have we reached the maximum number of tries?
jl rfil21 ; If not proceed.
mov dx,offset ermes9
jmp rcverr ; do error exit
rfil21: mov ax,pack.pktnum ; Get the present packet number.
cmp ax,0 ; Had we wrapped around?
jne rfily
mov ax,64
rfily: dec ax ; Decrement.
cmp ax,pack.argblk ; Is the packet's number one less than now?
je rfil24
jmp nak0 ; No, NAK and try again.
rfil24: mov pack.numtry,0
mov pack.argbk1,0 ; No data. (The packet number is in argblk.)
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
ret
rfile3: cmp ah,'F' ; Start of file (F or X packet)?
je rfil31 ; e = yes.
cmp ah,'X' ; Text header packet?
jne rfile4 ; Neither one.
mov flags.xflg,1 ; 'X', say receiving to the screen
rfil31: mov ax,pack.argblk ; Get the packet number.
cmp ax,pack.pktnum ; Is it the right packet number?
je rfil32
jmp nak1 ; No, NAK it and try again.
rfil32: inc ax ; Increment the packet number.
and ax,3FH ; Turn off the two high order bits.
mov pack.pktnum,ax ; Save modulo 64 of the number.
inc pack.numpkt ; Increment the number of packets.
mov filopn,0 ; assume not writing to a disk file
mov ax,0 ; tell statistics this was a receive operation
call endtim ; get tod & size of file transfer
call gofil ; Get a file to write to.
jmp abort
call begtim ; start next statistics group
mov chrcnt,maxpack ; reset output buffer to be empty
cmp flags.xflg,0 ; writing to a disk file?
jne rfil32a ; ne = no
mov filopn,2 ; Disk file open for writing
rfil32a:
test flags.remflg,dserial ; serial display mode?
jz rfil33 ; z = no
mov ah,prstr
mov dx,offset crlf ; display cr/lf
int dos
rfil33:
mov pack.numtry,0 ; Reset the number of tries.
mov pack.argbk1,0 ; No data. (The packet number is in argblk.)
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
mov pack.state,'D' ; Set the state to data receive.
ret
rfile4: cmp ah,'B' ; End of transmission?
jne rfile5 ; ne = no
mov ax,pack.pktnum
cmp ax,pack.argblk ; Do we match?
je rfil41
jmp nak1 ; No, NAK it and try again.
rfil41: mov pack.argbk1,0 ; No data. (Packet number already in argblk).
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
mov pack.state,'C' ; Set the state to complete.
ret
rfile5: cmp ah,'E' ; Is it an error packet?
jne rfile6 ; ne = no
call error
rfile6: jmp abort
RFILE ENDP
; Receive data
RDATA PROC NEAR
mov dl,maxtry
cmp pack.numtry,dl ; Get the number of tries.
jl rdata1
mov dx,offset erms10
jmp rcverr ; do error exit
rdata1: inc pack.numtry ; Save the updated number of tries.
call rpack ; Get a packet.
jmp nak0 ; Trashed packet: nak, retry.
call pktsize ; report packet size
cmp ah,'D' ; Is it a data packet?
je rdat11 ; e = yes
call dodec ; Decode data.
jmp rdata2 ; No, try next type.
; D packets
rdat11: mov ax,pack.pktnum ; Get the present packet number.
cmp ax,pack.argblk ; Is the packet's number correct?
jz rdat14
mov dl,maxtry
cmp pack.numtry,dl ; Have we reached the maximum number of tries?
jl rdat12 ; If not proceed.
mov dx,offset erms10
jmp rcverr ; do error exit
rdat12: mov ax,pack.pktnum
cmp ax,0 ; Had we wrapped around?
jne rdatx
mov ax,64
rdatx: dec ax
cmp ax,pack.argblk ; Is the packet's number one less than now?
je rdat13
jmp nak0 ; No, NAK it and try again.
rdat13: mov pack.numtry,0 ; Reset number of tries.
mov pack.argbk1,0 ; No data. (The packet number is in argblk.)
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
ret
rdat14: inc pack.pktnum ; Increment the packet number
and pack.pktnum,3fh ; Save modulo 64 of the number
inc pack.numpkt ; Increment the number of packets.
mov ax,pack.argbk1 ; Get the length of the data.
cmp flags.cxzflg,0 ; Has the user typed a ^X or ^Z?
je rdt14x ; No, write out the data.
cmp flags.abfflg,1 ; Discard incomplete files?
je rdat15 ; If yes don't write data out to file.
rdt14x: call ptchr ; decode the data and output to file
jmp abort ; Unable to write out chars; abort.
rdat15: mov pack.numtry,0 ; Reset the number of tries.
mov pack.argbk1,0 ; No data. (Packet number still in argblk.)
cmp flags.cxzflg,0 ; Interrupt file transfer?
je rdat16 ; Nope.
mov bx,offset data ; Send data in ACK in case remote
mov ah,flags.cxzflg ; knows about ^X/^Z.
mov [bx],ah ; Put data into the packet.
mov pack.argbk1,1 ; Set data size to 1.
mov cx,1
call doenc
rdat16: mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
ret
rdata2: cmp ah,'F' ; Start of file?
je rdat20 ; e = yes
cmp ah,'X' ; Text header packet?
jne rdata3 ; No, try next type.
rdat20: mov dl,maxtry ; F or X packet
cmp pack.numtry,dl ; Reached the max number of tries?
jl rdat21 ; If not proceed.
mov dx,offset ermes8
jmp rcverr ; do error exit
rdat21: mov ax,pack.pktnum
cmp ax,0 ; Had we wrapped around?
jne rdaty
mov ax,64
rdaty: dec ax
cmp ax,pack.argblk ; Is the packet's number one less than now?
je rdat22
jmp nak0 ; No, NAK it and try again.
rdat22: mov pack.numtry,0 ; Reset number of tries.
mov pack.argbk1,0 ; No data. (The packet number is in argblk.)
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
ret
rdata3: cmp ah,'Z' ; Is it a EOF packet?
je rdat3x ; e = yes
jmp rdata4 ; Try and see if its an error.
rdat3x: mov ax,pack.pktnum ; Get the present packet number.
cmp ax,pack.argblk ; Is the packet's number correct?
je rdat32
jmp nak0 ; No, NAK it and try again.
rdat32: inc ax ; Increment the packet number.
and ax,3FH ; Turn off the two high order bits.
mov pack.pktnum,ax ; Save modulo 64 of the number.
inc pack.numpkt
cmp flags.cxzflg,0 ; Do we want to discard the file?
jne rdt32x ; Yes.
cmp pack.argbk1,1 ; One piece of data?
jne rdat33 ; Nope - finish writing out file?
cmp data,'D' ; is the data "D" for discard?
jne rdat33 ; Nope - write out file.
rdt32x: cmp flags.abfflg,0 ; Keep incomplete files?
je rdat33 ; Yes, go write it out.
cmp flags.xflg,1 ; Writing to the screen?
je rdt32y ; Don't close "file".
cmp flags.destflg,2 ; file destination = screen?
je rdt32y ; e = yes, no file to close
push bx
mov ah,close2 ; DOS 2.0 file close
mov bx,diskio.handle ; file handle
int dos ; Kill it, ignore errors.
pop bx
mov filopn,0 ; File closed now.
mov dx,offset diskio.string ; get the filename
mov ah,del2 ; DOS 2.0 file delete
int dos
rdt32y: cmp flags.cxzflg,'X' ; Kill one file or all?
jne rdat36 ; No so leave flag alone.
call cxmsg ; Clear msg about interrupt.
test flags.remflg,dquiet ; quiet display?
jnz rdt32z ; nz = yes
cmp flags.destflg,2 ; Receiving to the screen?
je rdt32z ; e = yes, no formatted display
call intmsg
rdt32z: mov flags.cxzflg,0 ; Reset - ^X only kills one file
jmp rdat36
rdat33: cmp flags.eofcz,0 ; should we write a ^Z?
jz rdat35 ; no, keep going
cmp flags.xflg,0 ; writing to a file?
jne rdat35 ; no, skip ^Z
rdt33x: cmp chrcnt,0 ; any space left in output buffer?
jg rdat34 ; g = yes
call outbuf ; Write out buffer if no room for ^Z.
jmp abort
rdat34: mov cl,'Z'- 40h ; Put in a ^Z for EOF.
push bx
mov bx,bufpnt ; Get the dma pointer
mov [bx],cl ; Add it.
pop bx
dec chrcnt
rdat35: call outbuf ; Output the last buffer.
jmp abort ; Give up if the disk is full.
cmp flags.xflg,1 ; Writing to the screen?
je rdat37 ; Yes, don't close "file".
cmp flags.destflg,2 ; file destination = screen?
je rdat37 ; e = yes, no file to close
mov ah,close2 ; DOS 2.0 file close
push bx
mov bx,diskio.handle ; file handle
int dos
pop bx
mov filopn,0 ; File closed now.
rdat36: cmp flags.destflg,0 ; Writing to printer?
jne rdat37 ; ne = no, skip next part.
cmp flags.xflg,1 ; Writing to screen?
je rdat37 ; Yes, skip this part.
mov dl,ff ; Send a form feed.
mov ah,lstout ; Write out to first printer.
int dos
rdat37: mov pack.numtry,0 ; Reset the number of tries.
mov pack.argbk1,0 ; No data. (The packet number is in argblk.)
mov ah,'Y' ; Acknowledge packet.
call spack ; Send the packet.
jmp abort
mov pack.state,'F'
ret
rdata4: cmp ah,'E' ; Is it an error packet?
jne rdata5 ; ne = no
call error
rdata5: jmp abort
RDATA ENDP
; Error exit. Enter with dx pointing to error message. [jrd]
rcverr proc near
test flags.remflg,dquiet; quiet display mode?
jnz rcver1 ; nz = yes. Don't write to screen
cmp flags.destflg,2 ; Receiving to the screen?
je rcver1 ; e = yes, no formatted display
call erpos ; Position cursor.
mov ah,prstr
int dos ; Print an error message.
rcver1: mov bx,dx ; set bx to error message
call errpack ; Send error packet just in case.
jmp abort ; Change the state to abort.
rcverr endp
; Jumping to this location is like retskp. It assumes the instruction
; after the call is a jmp addr.
RSKP PROC NEAR
pop bp
add bp,3
push bp
ret
RSKP ENDP
R PROC NEAR
ret
R ENDP
code ends
end