home *** CD-ROM | disk | FTP | other *** search
Text File | 1984-07-15 | 23.4 KB | 1,345 lines |
- ;
- ; SENDRECV.A86
- ;
- ;Christensen protocol routines for MODEM9.xx.
- ;
- ;SEND A CP/M FILE
- ;
- SENDFIL:
- MOV CKSUMFLG,TRUE ;ALWAYS FORCE CHECKSUM MODE INITIALLY ON SEND
- CALL CKMODM ;REMOVE GARBAGE FROM LINE
- SENDFIL1:
- TEST BATCHFLG,0FFH ;CHECK IF MULTIPLE FILE..
- JNZ SENDC1
- CALL ILPRT
- DB 'Ready to send in the batch mode',CR,LF,0
- MOV SENDFLG,TRUE ;INDICATE SEND FOR BATCH MODE
- MOV AL,FSTFLG ;IF FIRST TIME THRU..
- OR AL,AL ;..SCAN THE COMMAND LINE..
- JZ SENDFIL2
- CALL TNMBUF ;..FOR MULTIPLE NAMES.
- SENDFIL2:
- CALL SENDFN ;SENDS FILE NAME TO RECEIVER
- JNC SENDC2 ;CARRY SET MEANS NO MORE FILES.
- MOV BATCHFLG,'B' ;STOP BATCH ....MODE OPTION.
- MOV AL,EOT ;FINAL XFER END
- CALL SEND
- JMP DONE
- ;
- SENDC1:
- CMP BYTE PTR .FCB+1,' '
- JNZ SENDC2
- JMP BLKFILE
-
- SENDC2:
- CALL CNREC ;GET NUMBER OF RECORDS
- CALL OPENFIL
- MOV DL,80
- CALL WAITNAK
-
- SENDLP:
- CALL CKABORT ;WANT TO TERMINATE WHLE SENDING FILE?
- CALL RDSECT
- JC SENDEOF
- CALL INCRSNO
- MOV ERRCT,1
- SENDRPT:
- CALL CKABORT ;WANT TO TERMINATE WHILE SENDING FILE?
- CALL SENDHDR
- CALL SENDSEC
- MOV AL,CKSUMFLG
- OR AL,AL
- JNZ SENDRPT1
- CALL SENDCRC
- JMPS SENDRPT2
-
- SENDRPT1:
- CALL SENDCKS
- SENDRPT2:
- CALL GETACK
- JC SENDRPT
- JMP SENDLP
- ;
- SENDEOF:
- MOV AL,EOT
- CALL SEND
- CALL GETACK
- JC SENDEOF
- JMP DONE
- ;
- ;RECEIVE A FILE
- ;
- RCVFIL:
- MOV AL,CKSUMDFLT ;GET MODE REQUESTED BY OPERATOR
- MOV CKSUMFLG,AL ;STORE IT
- CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
- RCVFIL1:
- MOV AL,BATCHFLG ;CHECK IF MULT..
- OR AL,AL ;..FILE MODE.
- JNZ RCVC1
- MOV AL,FALSE ;FLAG WHERE TO RETURN..
- MOV SENDFLG,AL ;..FOR NEXT FILE TRANS.
- CALL GETFN ;GET THE FILE NAME.
- JNC RCVC2 ;CARRY SET MEANS NO MORE FILES.
- MOV AL,'B' ;STOP BATCH..
- MOV BATCHFLG,AL ;..MODE OPTION.
- JMP DONE
- ;
- RCVC1:
- MOV AL,BYTE PTR .FCB+1 ;MAKE SURE FILE IS NAMED
- CMP AL,' '
- JNZ RECV1A
- JMP BLKFILE
-
- RECV1A:
- JMP RCVC3
- ;
- RCVC2:
- CALL CKCPM2
- CALL CKBAKUP
- RCVC3:
- CALL ERASFIL
- CALL MAKEFIL
- MOV AL,BATCHFLG ;DON'T PRINT MSG IF IN BATCH
- OR AL,AL
- JZ RCVFST
- CALL ILPRTQ
- DB 'File open, ready to receive',CR,LF,0
- RCVFST:
- MOV AL,CKSUMFLG
- OR AL,AL
- MOV AL,NAK
- JNZ RCVFIL2
- MOV AL,CRC
- RCVFIL2:
- CALL SEND
- MOV AL,CKSUMFLG
- OR AL,AL
- JNZ RCVNAKM ;IF IN CRC MODE
- CALL ILPRTQ ;THEN SAY SO
- DB 'CRC in effect',CR,LF,0
- JMP RCVLP
-
- RCVNAKM:
- CALL ILPRTQ ;ELSE SAY CHECKSUM MODE
- DB 'Checksum in effect',CR,LF,0
- RCVLP:
- CALL RCVSECT
- JC RCVEOT
- CALL WRSECT
- CALL INCRSNO
- CALL SENDACK
- JMP RCVLP
- ;
- RCVEOT:
- CALL WRBLOCK
- CALL SENDACK
- CALL CLOSFIL
- JMP DONE
- ;
- ;SUBROUTINES
- ;
- SENDFN:
- CALL ILPRTQ
- DB 'Awaiting name NAK',CR,LF,0
- MOV DL,80
- CALL WAITNLP
- MOV AL,ACK ;GOT NAK, SEND ACK
- CALL SEND
- MOV BX,OFFSET FILECT
- DEC BYTE PTR [BX]
- JS NOMRNM
- MOV BX,NBSAVE ;GET FILE NAME..
- MOV DX,OFFSET FCB ;..IN FCB
- MOV CH,12
- CALL MOVE
- MOV NBSAVE,BX
- CALL SENDNM ;SEND IT
- OR AL,AL ;CLEAR CARRY
- RET
- ;
- NOMRNM:
- MOV AL,EOT
- CALL SEND
- STC
- RET
- ;
- SENDNM:
- PUSH BX
- SENDNM1:
- MOV DH,11 ;COUNT CHARS IN NAME
- MOV CL,0 ;INIT CHECKSUM
- MOV AL,CL
- MOV FTYCNT,AL ;INITIATE FILE TYPE COUNT
- MOV BX,OFFSET FCB+1 ;ADDRESS NAME
- NAMLPS:
- MOV AL,BYTE PTR [BX] ;SEND NAME
- AND AL,07FH ;STRIP HIGH ORDER BIT SO CP/M 2..
- CALL SEND ;..WON'T SEND R/O FILE DESIGNATION.
- MOV AL,QFLG ;SHOW NAME IF..
- OR AL,AL ;..QFLG NOT SET.
- MOV AL,BYTE PTR [BX]
- JZ ACKLP
- CALL FTYTST ;TYPE CHARACTER ETC.
- ACKLP:
- PUSH CX ;SAVE CKSUM
- MOV CH,1 ;WAIT FOR RECEIVER..
- CALL RECV ;..TO ACKNOWLEDGE..
- POP CX ;..GETTING LETTER.
- JC SCKSER
- CMP AL,ACK
- JNZ ACKLP
- INC BX ;NEXT CHAR
- DEC DH
- JNZ NAMLPS
- MOV AL,EOFCHAR ;TELL RECEIVER END OF NAME
- CALL SEND
- MOV AL,QFLG
- OR AL,AL
- JZ ACKLP1
- CALL CRLF
- ACKLP1:
- MOV DH,CL ;SAVE CHECKSUM
- MOV CH,1
- CALL RECV ;GET CHECKSUM..
- CMP AL,DH ;..FROM RECEIVER.
- JZ NAMEOK
- SCKSER: MOV AL,BDNMCH ;BAD NAME-TELL RECEIVER
- CALL SEND
- CALL ILPRTQ
- DB 'Checksum error',CR,LF,0
- MOV DL,80 ;DO HANDSHAKING OVER
- CALL WAITNLP ;DON'T PRINT "AWAITING NAK" MSG
- MOV AL,ACK
- CALL SEND
- JMP SENDNM1
- ;
- NAMEOK:
- MOV AL,OKNMCH ;GOOD NAME, TELL RECEIVER
- CALL SEND
- POP BX
- RET
- ;
- GETFN: MOV BX,OFFSET FCB
- CALL INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
- CALL ILPRTQ
- DB 'Awaiting file name',CR,LF,0
- GNAMELP:
- CALL HSNAK
- CALL GETNM ;GET THE NAME
- CMP AL,EOT ;IF EOT, THEN NO MORE FILES
- JZ NOMRNMG
- OR AL,AL ;CLEAR CARRY
- RET
- ;
- NOMRNMG:
- STC
- RET
- ;
- GETNM:
- PUSH BX
- GETNM1:
- MOV CL,0 ;INIT CHECKSUM
- MOV AL,CL
- MOV FTYCNT,AL ;INITIATE COUNT FOR FILE TYPE
- MOV BX,OFFSET FCB+1
- NAMELPG:
- MOV CH,5
- CALL RECV ;GET CHAR
- JNC GETNM3
- CALL ILPRTQ
- DB 'Time out receiving filename',CR,LF,0
- JMP GCKSER
- ;
- GETNM3:
- CMP AL,EOT ;IF EOT, THEN NO MORE FILES
- JNZ GETNM4
- JMP GNRET
-
- GETNM4:
- CMP AL,EOFCHAR ;GOT END OF NAME
- JZ ENDNAME
- MOV BYTE PTR [BX],AL ;PUT NAME IN FCB
- MOV AL,QFLG ;CAN TYPE IT IF NO QFLG
- OR AL,AL
- JZ SKPTYP
- CALL FTYTST
- SKPTYP:
- PUSH CX ;SAVE CKSUM
- MOV AL,ACK ;ACK GETTING LETTER
- CALL SEND
- POP CX
- INC BX ;GET NEXT CHAR
- MOV AL,BL ;DON'T LET NOISE...
- CMP AL,7FH ;..CAUSE OVERFLOW..
- JZ GCKSER ;..INTO PROGRAM AREA.
- JMP NAMELPG
- ;
- FTYTST:
- INC FTYCNT
- CMP FTYCNT,9 ; ARE WE AT THE FILE TYPE?
- JZ SPCTST ;GO IF SO
- ENDSPT:
- MOV AL,BYTE PTR [BX]
- CMP AL,' ' ;TEST FOR SPACE
- JZ ENDSPT1
- CALL TIPE ;TYPE IF NOT
- ENDSPT1:
- RET
- ;
- SPCTST:
- MOV AL,BYTE PTR [BX]
- CMP AL,' ' ;TEST FOR SPACE IN FIRST FILE TYPE BYTE
- JZ ENDSPT1 ;DON'T OUTPUT PERIOD IF SPACE
- ; MJM 9.01.05 WAS JMPS
- MOV AL,'.'
- CALL TIPE
- JMP ENDSPT ;OUTPUT FIRST FILE TYPE BYTE
- ;
- ENDNAME:
- MOV AL,QFLG
- OR AL,AL
- JZ ENDNAME1
- CALL CRLF
- ENDNAME1:
- MOV AL,CL ;SEND CHECKSUM
- CALL SEND
- MOV CH,1
- CALL RECV ;CHECKSUM GOOD?
- CMP AL,OKNMCH ;YES IF OKNMCH SENT..
- JZ GNRET ;..ELSE DO OVER.
- GCKSER:
- MOV BX,OFFSET FCB ;CLEAR FCB (EXCEPT DRIVE)..
- CALL INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
- CALL ILPRTQ
- DB CR,LF,'++ Checksum error ++',CR,LF,0
- CALL HSNAK ;DO HANDSHAKING OVER
- JMP GETNM1
- ;
- GNRET:
- POP BX
- RET
- ;
- HSNAK:
- MOV DL,180 ;3-MINUTE MAXIMUM WAIT FOR A FILE NAME
- HSNAK1:
- CALL CKABORT ;WANT TO ABORT?
- MOV AL,NAK ;SEND NAK UNTIL RECEIVING ACK
- CALL SEND
- MOV CH,1 ;WAIT UP TO 1 SECOND FOR A CHARACTER
- CALL RECV
- CMP AL,ACK ;'ACK' IS WHAT WE WERE WAITING FOR
- JNZ HSNAK2
- RET
-
- HSNAK2:
- DEC DL ;ONE LESS TO TRY
- JNZ HSNAK1
- JMP ABORT ;TIMED OUT, ABORT BACK TO COMMAND LINE
- ;
- TNMBUF:
- MOV AL,FALSE ;CALL FROM SENDFIL ONLY ONCE.
- MOV FSTFLG,AL
- MOV FILECT,AL
- CALL SCAN
- MOV BX,OFFSET NAMEBUF
- MOV NBSAVE,BX ;SAVE ADDR OF 1ST NAME
- TNLP1:
- CALL TRTOBUF
- MOV BX,OFFSET FCB
- MOV DX,OFFSET FCBBUF
- CALL CPMLINE ;PARSE NAME TO CP/M FORMAT
- TNLP2:
- CALL MFNAME ;SEARCH FOR NAMES (* FORMAT)
- JC NEXTNM
- MOV AL,BYTE PTR .FCB+10 ;IF CP/M 2 $SYS FILE..
- AND AL,80H ;..DON'T SEND
- JNZ TNLP2
- MOV BX,NBSAVE ;GET NAME
- MOV DX,OFFSET FCB ;MOVE IT TO FCB
- XCHG BX,DX
- MOV CH,12
- CALL MOVE
- XCHG BX,DX
- MOV NBSAVE,BX ;ADDR OF NEXT NAME
- MOV BX,OFFSET FILECT ;COUNT FILES FOUND
- INC BYTE PTR [BX]
- JMP TNLP2
- ;
- NEXTNM:
- MOV BX,OFFSET SNAMECT ;COUNT NAMES FOUND
- DEC BYTE PTR [BX]
- JNZ TNLP1
- MOV BX,OFFSET NAMEBUF ;SAVE START OF BUFFER
- MOV NBSAVE,BX
- MOV AL,FILECT
- CMP AL,65 ;NO MORE THAN 64 TRANSFERS
- JNC NEXTNM1
- RET
-
- NEXTNM1:
- MOV AL,64 ;ONLY X'FER FIRST 64
- MOV FILECT,AL
- RET
- ;
- ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
- ;AFTER LAST NAME
- ;
- SCAN:
- PUSH BX
- MOV BX,OFFSET SNAMECT
- MOV BYTE PTR [BX],0
- MOV BX,OFFSET CMDBUF+1 ;FIND END OF CMD LINE..
- MOV CL,BYTE PTR [BX] ;..AND PUT SPACE THERE.
- MOV CH,0
- MOV BX,OFFSET CMDBUF+2
- ADD BX,CX
- MOV BYTE PTR [BX],20H
- MOV BX,OFFSET CMDBUF+1
- MOV CH,BYTE PTR [BX]
- INC CH
- INC CH
- SCANLP1:
- INC BX
- DEC CH
- JZ DNSCAN
- MOV AL,BYTE PTR [BX]
- CMP AL,20H
- JNZ SCANLP1
- SCANLP2:
- INC BX ;EAT EXTRA SPACES
- DEC CH
- JZ DNSCAN
- MOV AL,BYTE PTR [BX]
- CMP AL,20H
- JZ SCANLP2
- MOV BGNMS,BX ;SAVE START OF NAMES IN CMDBUF
- INC CH
- DEC BX
- SCANLP3:
- INC BX
- DEC CH
- JZ DNSCAN
- MOV AL,BYTE PTR [BX]
- CMP AL,20H
- JNZ SCANLP3
- MOV AL,SNAMECT ;COUNTS NAMES
- INC AL
- MOV SNAMECT,AL
- SCANLP4:
- INC BX ;EAT SPACES
- DEC CH
- JZ DNSCAN
- MOV AL,BYTE PTR [BX]
- CMP AL,20H
- JZ SCANLP4
- JMP SCANLP3
- ;
- DNSCAN:
- MOV BYTE PTR [BX],20H ;SPACE AFTER LAST CHAR
- POP BX
- RET
- ;
- ;PLACES NEXT NAME IN BUFFER SO 'CPMLINE' MAY PARSE IT
- ;
- TRTOBUF:
- MOV BX,BGNMS
- MOV CH,0
- MOV DX,OFFSET FCBBUF+2
- TBLP:
- MOV AL,BYTE PTR [BX]
- CMP AL,20H
- JZ TRBFEND
- XCHG BX,DX
- MOV BYTE PTR [BX],AL
- XCHG BX,DX
- INC BX
- INC DX
- INC CH ;COUNT CHARS IN NAME
- JMP TBLP
- ;
- TRBFEND:
- INC BX
- MOV AL,BYTE PTR [BX] ;EAT EXTRA SPACES
- CMP AL,20H
- JZ TRBFEND
- MOV BGNMS,BX
- MOV BX,OFFSET FCBBUF+1 ;PUT # CHARS BEFORE NAME
- MOV BYTE PTR [BX],CH
- RET
- ;
- RCVSECT:
- MOV AL,1
- MOV ERRCT,AL
- RCVRPT:
- CALL CKABORT ;WANT TO STOP RECEIVING FILE?
- MOV AL,QFLG
- OR AL,AL
- JZ RCVSQ
- CALL ILPRT
- DB CR,'Awaiting # ',0
- PUSH BX ;SAVE IT
- MOV BX,SECTNO ;GET SECTOR NUMBER
- INC BX ;BUMP IT
- CALL DECOUT ;PRINT SECTOR NUMBER IN DECIMAL
- CALL ILPRT
- DB ' (', 0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- MOV AL,BL ;ONLY LOW BYTE USED BY PROGRAM
- POP BX ;RESTORE IT
- RCVSQ: ;WAIT FOR SOH OR EOT
- MOV CH,10 ;10 SECONDS
- CALL RECV
- JNC RCVSQ1
- JMP RCVSTOT
-
- RCVSQ1:
- CMP AL,SOH
- JNZ RCVSQ2
- JMP RCVSOH
-
- RCVSQ2:
- OR AL,AL
- JZ RCVSQ
- CMP AL,EOT
- STC
- JNZ RCVSQ3
- RET
-
- RCVSQ3:
- MOV CH,AL
- MOV AL,QFLG
- OR AL,AL
- JZ RCVSERR
- RCVSEH:
- MOV AL,CH
- CALL CRLF
- CALL HEXO
- CALL ILPRT
- DB 'H received not SOH - ',0
- RCVPRN:
- CALL SHOWERR ;DISPLAY ERROR COUNT
- RCVSERR:
- MOV CH,1 ;WAIT FOR 1 SEC..
- CALL RECV ;..WITH NO CHARS
- JNC RCVSERR ;LOOP UNTIL SENDER DONE
- CALL CKABORT ;WANT TO STOP RECEIVING NOW?
- MOV AL,CKSUMFLG ;GET CHECKSUM FLAG
- OR AL,AL ;CRC IN EFFECT?
- MOV AL,NAK ;PUT NAK IN ACCUM
- JNZ RCVSER2 ;NO, SEND THE NAK
- MOV AL,FIRSTME ;GET FIRST TIME SWITCH
- OR AL,AL ;HAS FIRST SOH BEEN RECEIVED?
- MOV AL,NAK ;PUT NAK IN ACCUM
- JZ RCVSER2 ;YES, THEN SEND NAK
- MOV AL,CRC ;TELL SENDER CRC IS IN EFFECT
- RCVSER2:
- CALL SEND ;..THE NAK or CRC request
- MOV AL,ERRCT ;ABORT IF..
- INC AL ;..WE HAVE REACHED..
- MOV ERRCT,AL ;..THE ERROR..
- CMP AL,ERRLIM ;..LIMIT?
- JNC RCVSER3
- JMP RCVRPT ;..NO, TRY AGAIN
-
- RCVSER3:
- MOV AL,QFLG
- OR AL,AL
- JZ RCVSABT
- RCVCKQ:
- CALL CKQUIT
- JNZ RCVSABT
- JMP RCVSECT
-
- RCVSABT:
- CALL CLOSFIL ;CLOSE THE PARTIAL FILE
- CALL NOASK ;DELETE PARTIAL FILE
- CALL ILPRT
- DB CR,LF,LF
- DB '++ File receive cancelled and unfinished file deleted ++'
- DB BELL,CR,LF,0
- JMP DONETCA
- ;
- RCVSTOT:
- MOV AL,QFLG
- OR AL,AL
- RCVSPT: CALL ILPRT
- DB CR,LF,'++ Timeout ',0
- CALL SHOWERR
- RCVSCRC:
- CALL RCVSCRC2
- JMP RCVSERR
- ;
- ;ROUTINE WILL SWITCH FROM CRC TO CHECKSUM IF ERCNT REACHES ERRCRC
- ;AND FIRSTME IS TRUE
- ;
- RCVSCRC2:
- MOV AL,ERRCT
- CMP AL,ERRCRC
- JNZ RCVSCRC3
- MOV AL,FIRSTME
- OR AL,AL
- JZ RCVSCRC3
- MOV AL,CKSUMFLG
- OR AL,AL
- JNZ RCVSCRC3
- NOT AL
- MOV CKSUMFLG,AL
- MOV CKSUMDFLT,AL
- CALL ILPRTQ
- DB '++ Switching to Checksum mode ++',CR,LF
- DB '++ Sender may not be CRC capable ++',CR,LF,BELL,0
- RCVSCRC3:
- RET
- ;
- ;Got SOH - get block #, block # complemented
- ;
- RCVSOH:
- XOR AL,AL ;ZERO ACCUM
- MOV FIRSTME,AL ;INDICATE FIRST SOH RECV'D
- MOV CH,1 ;TIMEOUT = 1 SEC
- CALL RECV ;GET SECTOR
- JNC RCVSOH1
- JMP RCVSTOT ;GOT TIMEOUT
-
- RCVSOH1:
- MOV DH,AL
- MOV CH,1
- CALL RECV
- JNC RCVSOH2
- JMP RCVSTOT
-
- RCVSOH2:
- NOT AL
- CMP AL,DH
- JZ RCVDATA
- MOV AL,QFLG
- OR AL,AL
- JNZ RCVBSE
- JMP RCVSERR
-
- RCVBSE:
- CALL ILPRT
- DB CR,LF,'++ Bad sector # in Header ',0
- JMP RCVPRN
- ;
- RCVDATA:
- MOV AL,DH
- MOV RCVSNO,AL
- MOV AL,1
- MOV DATAFLG,AL
- MOV CL,0
- CALL CLRCRC ;CLEAR CRC COUNTER
- MOV BX,OFFSET 80H
- RCVCHR:
- MOV CH,1
- CALL RECV
- JNC RCVCHR1
- JMP RCVSTOT
-
- RCVCHR1:
- MOV BYTE PTR [BX],AL
- INC BL
- JNZ RCVCHR
- MOV AL,CKSUMFLG
- OR AL,AL
- JZ RCVCRC
- MOV DH,CL ; 9.01.02 MJM 7/8/83
- XOR AL,AL
- MOV DATAFLG,AL
- MOV CH,1
- CALL RECV
- JNC RCVCHR2
- JMP RCVSTOT
-
- RCVCHR2:
- CMP AL,DH
- JNZ RCVCERR
- CHKSNUM:
- MOV AL,RCVSNO
- MOV CH,AL
- MOV AX,SECTNO
- CMP AL,CH
- JZ RECVACK
- INC AL
- CMP AL,CH
- JZ CHKSNUM1
- JMP ABORT
-
- CHKSNUM1:
- RET
- ;
- RCVCRC:
- MOV DL,2 ;NUMBER OF CRC BYTES
- RCVCRC2:
- MOV CH,1
- CALL RECV
- JNC RCVCRC3
- JMP RCVSTOT
-
- RCVCRC3:
- DEC DL
- JNZ RCVCRC2
- CALL CHKCRC
- OR AL,AL
- JZ CHKSNUM
- MOV AL,QFLG
- OR AL,AL
- JNZ RCVCRER
- JMP RCVSERR
-
- RCVCRER:
- CALL ILPRT
- DB CR,LF,'++ CRC error ',0
- JMP RCVPRN
- ;
- RCVCERR:
- MOV AL,QFLG
- OR AL,AL
- JNZ RCVCPR
- JMP RCVSERR
-
- RCVCPR:
- CALL ILPRT
- DB CR,LF,'++ Checksum error ',0
- JMP RCVPRN
- ;
- RECVACK:
- CALL SENDACK
- JMP RCVSECT
- ;
- SENDACK:
- MOV AL,ACK
- CALL SEND
- RET
- ;
- SENDHDR:
- MOV AL,QFLG
- OR AL,AL
- JZ SENDHNM
- CALL ILPRT
- DB CR,'Sending # ',0
- PUSH BX
- MOV BX,SECTNO ;GET SECTOR NUMBER
- CALL DECOUT ;PRINT IT IN DECIMAL
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;16 BIT HEX CONVERSION & OUTPUT
- CALL ILPRT
- DB 'H)',0
- POP BX
- SENDHNM:
- MOV AL,SOH
- CALL SEND
- MOV AX,SECTNO
- CALL SEND
- MOV AX,SECTNO
- NOT AL
- CALL SEND
- RET
- ;
- SENDSEC:
- MOV AL,1
- MOV DATAFLG,AL
- MOV CL,0
- CALL CLRCRC
- MOV BX,OFFSET 80H
- SENDC:
- MOV AL,BYTE PTR [BX]
- CALL SEND
- INC BL
- JNZ SENDC
- XOR AL,AL
- MOV DATAFLG,AL
- RET
- ;
- SENDCKS:
- MOV AL,CL
- CALL SEND
- RET
- ;
- SENDCRC:
- CALL FINCRC
- MOV AL,DH
- CALL SEND
- MOV AL,DL
- CALL SEND
- XOR AL,AL
- RET
- ;
- ;
- ;After a record is sent, a character is returned telling if it was re-
- ;ceived properly or not. An ACK allows the next record to be sent. A
- ;NAK sends an error message and the current record is again repeated.
- ;This occurs until the error limit has been reached. If the first NAK
- ;is missed, it waits up to 12 seconds before declaring a 2nd error.
- ;This insures there is no collision with the station attempting to send
- ;the NAK, since it waits only 10 seconds.
- ;
- GETACK:
- MOV CH,12 ;12 SECONDS
- CALL RECVDG ;WAIT FOR ACK OR NAK
- JNC GETACK1
- JMP GETATOT ;NO CHARACTER, TIMED OUT
-
- GETACK1:
- CMP AL,ACK
- JNZ NOTACK
- RET ;IF ACK RETURN AND SEND NEXT RECORD
-
- NOTACK:
- ;
- ;If the ACKNAK option is FALSE it will resend the sector when any char-
- ;acter other than ACK is received (including NAK).
- ;
- MOV CH,AL
- MOV AL,NAKONLY
- OR AL,AL
- JZ ALLOTH
- CMP AL,NAK ;WAS IT AN AUTHENTIC 'NAK'?
- JNZ GETACK ;IGNORE IF NEITHER 'ACK' NOR 'NAK'
- ;WILL EVENTUALLY TIME OUT
- ALLOTH:
- MOV AL,QFLG
- OR AL,AL
- JZ ACKERR
- CALL ILPRT
- DB CR,LF,'++ ',0
- MOV AL,CH
- CMP AL,NAK ;IS IT A 'NAK'?
- JZ GETACK2 ;SHOW 'NAK' IN THAT CASE
- CALL HEXO
- MOV AL,'H'
- CALL TIPE
- JMP GETACK3
- GETACK2:
- CALL ILPRT
- DB 'NAK',0
- GETACK3:
- CALL ILPRT ;PRINT THE ERROR MESSAGE
- DB ' received not ACK - ',0
- CALL SHOWERR ;SHOW THE ERROR NUMBER
- ACKERR:
- MOV AL,ERRCT
- INC AL
- MOV ERRCT,AL
- DEC AL
- CMP AL,ERRLIM
- JNC ACKERR1
- RET
-
- ACKERR1:
- MOV AL,QFLG
- OR AL,AL
- JZ CSABORT
- GACKV:
- CALL CKQUIT
- STC
- JNZ CSABORT
- RET
- CSABORT:
- CALL ERXIT
- DB CR,LF,'Can''t send sector -- Aborting',CR,LF,'$'
- GETATOT:
- MOV AL,QFLG
- OR AL,AL
- JZ ACKERR
- CALL ILPRT
- DB CR,LF,'++ Timeout on ACK - ',0
- CALL SHOWERR ;DISPLAY ERROR COUNT
- JMP ACKERR
- ;
- CKABORT:
- MOV AL,QFLG
- OR AL,AL
- JNZ CKABGO
- RET
-
- CKABGO:
- CALL STAT
- JNZ CKABGO1
- RET
-
- CKABGO1:
- CALL KEYIN
- CMP AL,CAN
- JZ ABORT
- RET
-
- ABORT:
- MOV CH,1
- CALL RECV
- JNC ABORT
- MOV AL,CAN
- CALL SEND
- ABORTW:
- MOV CH,1
- CALL RECV
- JNC ABORTW
- MOV AL,' '
- CALL SEND
- MOV AL,'B' ;TURN MULTI-FILE MODE..
- MOV BATCHFLG,AL ;..OFF SO ROUTINE ENDS.
- MOV AL,OPTION ;RECEIVING A FILE NOW?
- CMP AL,'R'
- JNZ ABORTW1
- JMP RCVSABT ;IF YES, CANCEL THE UNFINISHED FILE
-
- ABORTW1:
- CALL ILPRT
- DB CR,LF,LF,'++ File send cancelled ++',CR,LF,BELL,0
- JMP DONETCA
- ;
- INCRSNO:
- INC SECTNO ; INCREMENT SECTOR NUMBER
- MOV AX,SECTNO ; NEED IT IN LOW BYTE, DON'T CARE ABOUT HIGH
- RET
- ;
- ;----> RECV: Receive a character
- ;
- ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
- ;characters on the line. For example, having just sent a sector, calling
- ;RECVDG will delete any line noise induced characters LONG before the
- ;ACK/NAK would be received.
- ;
- RECVDG:
- CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
- RECV:
- PUSH DX
- MSEC:
- PUSH BX
- MOV BX,OFFSET 5000
- CALL FIXCNT
- PUSH BX
- POP DX
- POP BX
- CALL CKABORT
- MWTI:
- CALL RCVREADY
- JZ MCHAR
- DEC DL
- JNZ MWTI
- DEC DH
- JNZ MWTI
- DEC CH
- JNZ MSEC
- POP DX
- STC
- RET
- ;
- MCHAR:
- CALL INMODDATP
- POP DX
- PUSH AX
- CALL UPDCRC ;CALCULATE CRC
- ADD CL,AL
- MOV AL,RSEEFLG
- OR AL,AL
- JZ MONIN
- MOV AL,VSEEFLG
- OR AL,AL
- JNZ NOMONIN
- MOV AL,DATAFLG
- OR AL,AL
- JZ NOMONIN
- MONIN:
- POP AX
- PUSH AX
- CALL SHOW
- NOMONIN:
- POP AX
- OR AL,AL
- RET
- ;
- SEND:
- PUSH AX
- MOV AL,SSEEFLG
- OR AL,AL
- JZ MONOUT
- MOV AL,VSEEFLG
- OR AL,AL
- JNZ NOMONOT
- MOV AL,DATAFLG
- OR AL,AL
- JZ NOMONOT
- MONOUT:
- POP AX
- PUSH AX
- CALL SHOW
- NOMONOT:
- POP AX
- PUSH AX
- CALL UPDCRC ;CALCULATE CRC
- ADD CL,AL
- SENDW:
- CALL SENDREADY
- JNZ SENDW
- POP AX
- CALL OUTMODDATP
- RET
- ;
- WAITNAK:
- CALL ILPRTQ
- DB 'Awaiting initial NAK',CR,LF,0
- WAITNLP:
- CALL CKABORT
- MOV CH,1
- CALL RECV
- CMP AL,NAK
- JNZ WAITNLP1
- RET
-
- WAITNLP1:
- CMP AL,CRC ;CRC REQUEST?
- JZ WAITCRC ;YES, GO SET CRC FLAG
- CMP AL,CAN
- JNZ WAITNLP2
- JMP ABORT
-
- WAITNLP2:
- DEC DL
- JNZ WAITNLP
- JMP ABORT
- ;
- WAITCRC:
- CALL ILPRTQ
- DB 'CRC request received',CR,LF,0
- XOR AL,AL
- MOV CKSUMFLG,AL
- RET
- ;
- ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
- ;NO QUESTIONS ASKED, JUST QUIT
- ;
- CKQUIT:
- MOV AL,BATCHFLG
- OR AL,AL
- JNZ CKQTASK ;ASK FOR RETRY
- INC AL ;RESET ZERO FLG
- RET
- ;
- CKQTASK:
- MOV ERRCT,1
- CALL ILPRT
- DB CR,LF,'Multiple errors encountered.',CR,LF
- DB 'Type Q to quit, R to retry: ',BELL,0
- CALL KEYIN
- CALL CRLF
- CALL UCASE ;INSTEAD OF "ANI 5FH"
- CMP AL,'R'
- JZ CKQTASK1
- CMP AL,'Q'
- JNZ CKQUIT
- OR AL,AL
- CKQTASK1:
- RET
- ;
- ;Get the error count and display on CRT
- ;
- SHOWERR:
- PUSH BX ;SAVE THE CURRENT ADDRESS
- MOV BL,ERRCT ;GET THE CURRENT ERROR NUMBER
- MOV BH,0 ;ONLY A 8-BIT NUMBER, NOW IN 'L' REG.
- CALL DECOUT ;DISPLAY THE ERROR IN DECIMAL
- POP BX ;RESTORE THE CURRENT ADDRESS
- CALL ILPRT
- DB ' ++',CR,LF,0 ;FINISH THE ERROR MESSAGE
- RET
- ;
- ERXIT:
- POP DX
- CALL PRTMSG
- MOV AL,BELL
- CALL TIPE
- MOV AL,BATCHFLG
- OR AL,AL
- JZ ERXIT1
- JMP DONETCA
-
- ERXIT1:
- MOV AL,'Q' ;RESET QFLG
- MOV QFLG,AL
- JMP ABORT ;ABORT OTHER COMPUTER
- ;
- DONE:
- MOV AL,BATCHFLG
- OR AL,AL
- JZ DONE1
- JMP DONETC
-
- DONE1:
- MOV AL,QFLG
- OR AL,AL
- JZ NMSTRNS
- MOV CH,12 ;ZERO OUT FTRNMSG
- MOV BX,OFFSET FTRNMSG
- ZEROLP:
- MOV BYTE PTR [BX],' ' ; mjm 9.01.05 FIX BATCH NAME REPORT
- INC BX
- DEC CH
- JNZ ZEROLP
- MOV CH,12 ;PUT FILE NAME IN FTRNMSG
- MOV BX,OFFSET FCB+1
- MOV DX,OFFSET FTRNMSG
- LOADMSG:
- MOV AL,4 ;START OF FILE TYPE?
- CMP AL,CH
- JZ PERIOD ;PUT IN PERIOD IF SO
- MOV AL,BYTE PTR [BX]
- CMP AL,' ' ;DON'T PUT IN SPACE
- JZ SKPSP
- XCHG BX,DX
- MOV BYTE PTR [BX],AL ;STORE IN FTRNMSG
- XCHG BX,DX
- INC DX
- SKPSP:
- INC BX
- DEC CH
- MOV AL,CH
- OR AL,AL ;END OF FILE NAME?
- JZ FTRNMSG0 ;DISPLAY FILE NAME
- JMP LOADMSG ;LOOP FOR ANOTHER CHARACTER
- ;
- PERIOD:
- MOV AL,BYTE PTR [BX]
- CMP AL,' ' ;IS FILE TYPE EMPTY?
- JZ FTRNMSG0 ;GO IF SO
- MOV AL,'.' ;ELSE PUT PERIOD IN MESSAGE
- XCHG BX,DX
- MOV BYTE PTR [BX],AL
- XCHG BX,DX
- INC DX
- DEC CH
- JMP LOADMSG
- ;
- FTRNMSG0:
- CALL ILPRT
- DB CR,LF
- FTRNMSG RB 12
- DB 0
- CALL ILPRT
- DB ' Transferred',CR,LF,LF,0
- NMSTRNS:
- MOV AL,BYTE PTR .FCB ;SAVE DRIVE NO.
- MOV DISKNO,AL
- MOV BX,OFFSET FCB ;BLANK OUT FILE CONTROL BLOCKS
- CALL INITFCBS
- MOV AL,DISKNO ;PUT DRIVE NUMBER BACK
- MOV BYTE PTR .FCB,AL
- MOV BX,OFFSET RESTSN ;RESTORE SECTORE NUMBERS..
- MOV DX,OFFSET SECTNOB ;..FOR NEW FILE TRANSFER.
- MOV CH,OFFSET SECTNOE-OFFSET SECTNOB ;ROUTINE ALSO DONE IN MENU.
- CALL MOVE
- CALL CKMODM ;CATCH ANY GARBAGE CHARACTERS
- MOV AL,SENDFLG ;GOES TO EITHER SEND OR..
- OR AL,AL ;..RECEIVE FILE, DEPENDING..
- JZ NMSTRNS1
- JMP SENDFIL1 ;..UPON WHICH ROUTINE SET..
-
- NMSTRNS1:
- JMP RCVFIL1 ;..THE FLAG IN MULTI-FILE MODE.
- ;
- DONETC:
- CALL CKABORT ;SLIGHT DELAY FOR NEXT MESSAGE
- CALL ILPRT
- DB CR,LF,'All transfers completed',CR,LF,BELL,0
- DONETCA:
- MOV AL,TRUE
- MOV FIRSTME,AL ;SET FIRST-TIME FLAG
- MOV FSTFLG,AL ;RESET MULTIFILE TRANS
- MOV NFILFLG,AL ;..USED IN TERMINAL ROUTINE
- NOT AL
- MOV SAVEFLG,AL ;STOP MEMORY SAVE IN TERM ROUTINE
- MOV LISTMOR,AL ;STOP ANY BUFFERED OUTPUT TO PRINTER
- MOV BX,OFFSET BOTTRAM ;RESET PRINTER BUFFER POINTERS
- MOV HLSAVE1,BX
- MOV HLSAVE2,BX
- MOV AL,TERMFLG ;SEE IF RETURN TO..
- OR AL,AL ;..TERMINAL MODE..
- JNZ DONETCA1 ;..AFTER X'FER.
- CALL ILPRT
- DB CR,LF,'** Entering terminal mode **',CR,LF,LF,BELL,0
- JMP TERM
-
- DONETCA1:
- JMP MENU
- ;
- ;Shows the time to transfer a file at various baud rates
- ;
- SENDTIM:
- CALL ILPRT ;PRINT:
- DB 'File open: ',0
- MOV BX,RCNT ;GET RECORD COUNT.
- CALL DECOUT ;PRINT DECIMAL NUMBER OF RECORDS
- CALL ILPRT
- DB ' (',0
- CALL DHXOUT ;NOW PRINT SIZE IN HEX.
- CALL ILPRT
- DB ' Hex) Records',CR,LF
- DB 'Send time: ',0
- MOV AL,MSPEED ;GET THE SPEED INDICATOR
- MOV DH,0
- MOV DL,AL ;SET UP FOR TABLE ACCESS
- MOV BX,OFFSET BTABLE ;POINT TO BAUD FACTOR TABLE
- ADD BX,DX ;INDEX TO PROPER FACTOR
- ADD BX,DX
- MOV DL,BYTE PTR [BX];FACTOR IN DE
- INC BX
- MOV DH,BYTE PTR [BX]
- MOV BX,RCNT ;GET # OF RECORDS
- CALL DIVHLDE ;DIVIDE HL BY VALUE IN A (RECORDS/MIN)
- PUSH BX
- MOV BX,CX
- CALL DECOUT ;PRINT THE MINUTES PORTION
- CALL ILPRT
- DB ' mins, ',0
- MOV BX,OFFSET SECTBL ;POINT TO DIVISORS FOR SECONDS
- MOV DX,0 ; CALCULATION
- MOV AL,MSPEED ;GET INDEX FOR BAUD RATE
- MOV DL,AL
- ADD BX,DX ;INDEX INTO TABLE
- MOV AL,BYTE PTR [BX];GET MULTIPLIER = (SEC/REC) x 16
- POP BX ;GET REMAINDER
- CALL MULHLA ;MULTIPLY THE 'HL' x 'A'
- CALL SHFTHL ;DIVIDE BY 16
- CALL SHFTHL
- CALL SHFTHL
- CALL SHFTHL
- MOV BH,0
- CALL DECOUT ;PRINT THE SECONDS PORTION
- CALL ILPRT
- DB ' secs at ',0
- CALL BAUDPRT
- CALL ILPRT
- DB 'To cancel use ctrl-X',CR,LF,0
- RET
- ;
- ; CORRECTED BY M.J. MELLINGER FOR 9.01.05 11/25/83
- BTABLE DW 5,13,25,48,96,192,384,0 ;RECORDS/MIN FOR 110-9600 BAUD
- SECTBL DB 192,74,38,20,11,5,3,0
- ;
- ;
- ;----> DIVHLDE: DIVIDES 'HL' BY VALUE IN 'DE',
- ; UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER
- ;
- DIVHLDE:
- PUSH DX ;SAVE DIVISOR
- ; MOV AL,DL
- ; NOT AL ;NEGATE DIVISOR
- ; MOV DL,AL
- ; MOV AL,DH
- ; NOT AL
- ; MOV DH,AL
- ; INC DX ;DE IS NOW TWOS COMPLEMENTED
- NEG DX
- MOV CX,0 ;INITIATE QUOTIENT
- DIVL1:
- ADD BX,DX ;SUBTRACT DIVISOR FROM DIVIDEND
- INC CX ;INCREASE QUOTIENT
- JC DIVL1 ;LOOP UNTIL SIGN CHANGES
- DEC CX ;ADJUST QUOTIENT
- POP DX ;RETRIEVE DIVISOR
- ADD BX,DX ;ADJUST REMAINDER
- RET
-
- ;
- ;----> MULHLA: MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A'
- ; RETURN WITH ANSWER IN 'HL'
- ;
- MULHLA:
- XCHG BX,DX ;MULTIPLICAND TO DE
- MOV BX,OFFSET 0 ;INITIALIZE PRODUCT
- INC AL ;ADJUST MULTIPLIER
- MULLP:
- DEC AL
- JNZ MULLP1
- RET
-
- MULLP1:
- ADD BX,DX
- JMPS MULLP
- ;
- ; SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT
- ;
- SHFTHL:
- CLC ;CLEAR THE CARRY
- RCR BX,1
- RET
- ;
- ;****************************************************************
- ;* *
- ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20 *
- ;* 8080 Mnemonics *
- ;* *
- ;* These subroutines will compute and check a true 16-bit *
- ;* Cyclic Redundancy Code for a message of arbitrary length. *
- ;* *
- ;* The use of this scheme will guarantee detection of all *
- ;* single and double bit errors, all errors with an odd *
- ;* number of error bits, all burst errors of length 16 or *
- ;* less, 99.9969% of all 17-bit error bursts, and 99.9984% *
- ;* of all possible longer error bursts. (Ref: Computer *
- ;* Networks, Andrew S. Tanenbaum, Prentiss-Hall, 1981) *
- ;* *
- ;* Designed & coded by Paul Hansknecht, June 13, 1981 *
- ;* *
- ;* Copyright (c) 1981, Carpenter Associates *
- ;* Box 451 *
- ;* Bloomfield Hills, MI 48013 *
- ;* 313/855-3074 *
- ;* *
- ;* This program may be freely reproduced for non-profit use. *
- ;* *
- ;****************************************************************
- ;
- ;
- CLRCRC: ;RESET CRC ACCUMULATOR FOR A NEW MESSAGE.
- MOV CRCVAL,0
- RET
- ;
- UPDCRC: ;UPDATE CRC ACCUMULATOR USING BYTE IN (A).
- PUSH AX
- PUSH CX
- PUSH BX
- MOV CH,8
- MOV CL,AL
- MOV BX,CRCVAL
- UPDLOOP:
- ROL CL,1
- ; MOV AL,CL
- ; ROL AL,1
- ; MOV CL,AL
- RCL BX,1
- JNC SKIPIT
- XOR BX,1021H
- SKIPIT:
- DEC CH ;AND XOR 05H FOR XOR 21H IN THE ADJACENT CODE
- JNZ UPDLOOP
- MOV CRCVAL,BX
- POP BX
- POP CX
- POP AX
- RET
- ;
- FINCRC: ;FINISH CRC CALCULATION FOR OUTPUT MESSAGE
- PUSH AX
- XOR AL,AL
- CALL UPDCRC
- CALL UPDCRC
- MOV DX,CRCVAL
- POP AX
- RET
- ;
- CHKCRC: ;CHECK CRC BYTES OF RECEIVED MESSAGE
- MOV AX,CRCVAL
- OR AL,AH
- JZ CHKCRCRT
- MOV AL,0FFH
- CHKCRCRT:
- RET
- ;
- CRCVAL DW 0
- ;
-