home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / COMMS / MODEM9.ARC / SENDRECV.ASM < prev    next >
Assembly Source File  |  1991-02-02  |  23KB  |  1,231 lines

  1. ;
  2. ;        SENDRECV.ASM
  3. ;
  4. ;Christensen protocol routines for MODEM9.xx.
  5. ;
  6. ;SEND A CP/M FILE
  7. ;
  8. SENDFIL:
  9.     MVI    A,TRUE    ;ALWAYS FORCE CHECKSUM MODE INITIALLY ON SEND
  10.     STA    CKSUMFLG
  11.     CALL    CKMODM    ;REMOVE GARBAGE FROM LINE
  12. SENDFIL1:
  13.     LDA    BATCHFLG  ;CHECK IF MULTIPLE FILE..
  14.     ORA    A    ;..MODE IS SET.
  15.     JNZ    SENDC1
  16.     CALL    ILPRT
  17.     DB    'Ready to send in the batch mode',CR,LF,0
  18.     MVI    A,TRUE    ;INDICATE SEND FOR BATCH MODE
  19.     STA    SENDFLG
  20.     LDA    FSTFLG    ;IF FIRST TIME THRU..
  21.     ORA    A    ;..SCAN THE COMMAND LINE..
  22.     CNZ    TNMBUF    ;..FOR MULTIPLE NAMES.
  23.     CALL    SENDFN    ;SENDS FILE NAME TO RECEIVER
  24.     JNC    SENDC2    ;CARRY SET MEANS NO MORE FILES.
  25.     MVI    A,'B'    ;STOP BATCH..
  26.     STA    BATCHFLG  ;..MODE OPTION.
  27.     MVI    A,EOT    ;FINAL XFER END
  28.     CALL    SEND
  29.     JMP    DONE
  30. ;
  31. SENDC1:
  32.     LDA    FCB+1
  33.     CPI    ' '
  34.     JZ    BLKFILE
  35. SENDC2:
  36.     CALL    CNREC    ;GET NUMBER OF RECORDS
  37.     CALL    OPENFIL
  38.     MVI    E,80
  39.     CALL    WAITNAK
  40.  
  41. SENDLP: CALL    CKABORT        ;WANT TO TERMINATE WHLE SENDING FILE?
  42.     CALL    RDSECT
  43.     JC    SENDEOF
  44.     CALL    INCRSNO
  45.     MVI    A,1
  46.     STA    ERRCT
  47. SENDRPT:
  48.     CALL    CKABORT        ;WANT TO TERMINATE WHILE SENDING FILE?
  49.     CALL    SENDHDR
  50.     CALL    SENDSEC
  51.     LDA    CKSUMFLG
  52.     ORA    A
  53.     CZ    SENDCRC
  54.     CNZ    SENDCKS
  55.     CALL    GETACK
  56.     JC    SENDRPT
  57.     JMP    SENDLP
  58. ;
  59. SENDEOF:
  60.     MVI    A,EOT
  61.     CALL    SEND
  62.     CALL    GETACK
  63.     JC    SENDEOF
  64.     JMP    DONE
  65. ;
  66. ;RECEIVE A FILE
  67. ;
  68. RCVFIL:    LDA    CKSUMDFLT    ;GET MODE REQUESTED BY OPERATOR
  69.     STA    CKSUMFLG    ;STORE IT
  70.     CALL    CKMODM        ;CATCH ANY GARBAGE CHARACTERS
  71. RCVFIL1:
  72.     LDA    BATCHFLG ;CHECK IF MULT..
  73.     ORA    A    ;..FILE MODE.
  74.     JNZ    RCVC1
  75.     MVI    A,FALSE    ;FLAG WHERE TO RETURN..
  76.     STA    SENDFLG    ;..FOR NEXT FILE TRANS.
  77.     CALL    GETFN    ;GET THE FILE NAME.
  78.     JNC    RCVC2    ;CARRY SET MEANS NO MORE FILES.
  79.     MVI    A,'B'    ;STOP BATCH..
  80.     STA    BATCHFLG ;..MODE OPTION.
  81.     JMP    DONE
  82. ;
  83. RCVC1:    LDA    FCB+1    ;MAKE SURE FILE IS NAMED
  84.     CPI    ' '
  85.     JZ    BLKFILE
  86.     JMP    RCVC3
  87. ;
  88. RCVC2:    CALL    CKCPM2
  89.     CALL    CKBAKUP
  90. RCVC3:    CALL    ERASFIL
  91.     CALL    MAKEFIL
  92.     LDA    BATCHFLG    ;DON'T PRINT MSG IF IN BATCH
  93.     ORA    A
  94.     JZ    RCVFST
  95.     CALL    ILPRTQ
  96.     DB    'File open, ready to receive',CR,LF,0
  97. RCVFST:    LDA    CKSUMFLG
  98.     ORA    A
  99.     MVI    A,NAK
  100.     JNZ    RCVFIL2
  101.     MVI    A,CRC
  102. RCVFIL2:
  103.     CALL    SEND
  104.     LDA    CKSUMFLG
  105.     ORA    A
  106.     JNZ    RCVNAKM        ;IF IN CRC MODE
  107.     CALL    ILPRTQ        ;THEN SAY SO
  108.     DB    'CRC in effect',CR,LF,0
  109.     JMP    RCVLP
  110. RCVNAKM:
  111.     CALL    ILPRTQ        ;ELSE SAY CHECKSUM MODE
  112.     DB    'Checksum in effect',CR,LF,0
  113. RCVLP:
  114.     CALL    RCVSECT
  115.     JC    RCVEOT
  116.     CALL    WRSECT
  117.     CALL    INCRSNO
  118.     CALL    SENDACK
  119.     JMP    RCVLP
  120. ;
  121. RCVEOT:
  122.     CALL    WRBLOCK
  123.     CALL    SENDACK
  124.     CALL    CLOSFIL
  125.     JMP    DONE
  126. ;    
  127. ;SUBROUTINES
  128. ;
  129. SENDFN:    CALL    ILPRTQ
  130.     DB    'Awaiting name NAK',CR,LF,0
  131.     MVI    E,80
  132.     CALL    WAITNLP
  133.     MVI    A,ACK    ;GOT NAK, SEND ACK
  134.     CALL    SEND
  135.     LXI    H,FILECT
  136.     DCR    M
  137.     JM    NOMRNM
  138.     LHLD    NBSAVE    ;GET FILE NAME..
  139.     LXI    D,FCB    ;..IN FCB
  140.     MVI    B,12
  141.     CALL    MOVE
  142.     SHLD    NBSAVE
  143.     CALL    SENDNM    ;SEND IT
  144.     ORA    A    ;CLEAR CARRY
  145.     RET
  146. ;
  147. NOMRNM:    MVI A,EOT
  148.     CALL SEND
  149.     STC
  150.     RET
  151. ;
  152. SENDNM:    PUSH    H
  153. SENDNM1:
  154.     MVI    D,11    ;COUNT CHARS IN NAME
  155.     MVI    C,0    ;INIT CHECKSUM
  156.     MOV    A,C
  157.     STA    FTYCNT    ;INITIATE FILE TYPE COUNT
  158.     LXI    H,FCB+1    ;ADDRESS NAME
  159. NAMLPS:    MOV    A,M    ;SEND NAME
  160.     ANI    7FH    ;STRIP HIGH ORDER BIT SO CP/M 2..
  161.     CALL    SEND    ;..WON'T SEND R/O FILE DESIGNATION.
  162.     LDA    QFLG    ;SHOW NAME IF..
  163.     ORA    A    ;..QFLG NOT SET.
  164.     MOV    A,M
  165.     CNZ    FTYTST    ;TYPE CHARACTER ETC.
  166. ACKLP:    PUSH    B    ;SAVE CKSUM
  167.     MVI    B,1    ;WAIT FOR RECEIVER..
  168.     CALL    RECV    ;..TO ACKNOWLEDGE..
  169.     POP    B    ;..GETTING LETTER.
  170.     JC    SCKSER
  171.     CPI    ACK
  172.     JNZ    ACKLP
  173.     INX    H    ;NEXT CHAR
  174.     DCR    D
  175.     JNZ    NAMLPS
  176.     MVI    A,EOFCHAR ;TELL RECEIVER END OF NAME
  177.     CALL    SEND
  178.     LDA    QFLG
  179.     ORA    A
  180.     CNZ    CRLF
  181.     MOV    D,C    ;SAVE CHECKSUM
  182.     MVI    B,1
  183.     CALL    RECV    ;GET CHECKSUM..
  184.     CMP    D    ;..FROM RECEIVER.
  185.     JZ    NAMEOK
  186. SCKSER:    MVI    A,BDNMCH ;BAD NAME-TELL RECEIVER
  187.     CALL    SEND
  188.     CALL    ILPRTQ
  189.     DB    'Checksum error',CR,LF,0
  190.     MVI    E,80    ;DO HANDSHAKING OVER
  191.     CALL    WAITNLP    ;DON'T PRINT "AWAITING NAK" MSG
  192.     MVI    A,ACK
  193.     CALL    SEND
  194.     JMP    SENDNM1
  195. ;
  196. NAMEOK:
  197.     MVI    A,OKNMCH ;GOOD NAME-TELL RECEIVER
  198.     CALL    SEND
  199.     POP    H
  200.     RET    
  201. ;
  202. GETFN:    LXI    H,FCB
  203.     CALL    INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
  204.     CALL    ILPRTQ
  205.     DB    'Awaiting file name',CR,LF,0
  206. GNAMELP:
  207.     CALL    HSNAK
  208.     CALL    GETNM    ;GET THE NAME
  209.     CPI    EOT    ;IF EOT, THEN NO MORE FILES
  210.     JZ    NOMRNMG
  211.     ORA    A    ;CLEAR CARRY
  212.     RET
  213. ;
  214. NOMRNMG:
  215.     STC
  216.     RET
  217. ;
  218. GETNM:
  219.     PUSH    H
  220. GETNM1:
  221.     MVI    C,0    ;INIT CHECKSUM
  222.     MOV    A,C
  223.     STA    FTYCNT    ;INITIATE COUNT FOR FILE TYPE
  224.     LXI    H,FCB+1
  225. NAMELPG:
  226.     MVI    B,5
  227.     CALL    RECV    ;GET CHAR
  228.     JNC    GETNM3
  229.     CALL    ILPRTQ
  230.     DB    'Time out receiving filename',CR,LF,0
  231.     JMP    GCKSER
  232. ;
  233. GETNM3:
  234.     CPI    EOT    ;IF EOT, THEN NO MORE FILES
  235.     JZ    GNRET
  236.     CPI    EOFCHAR    ;GOT END OF NAME
  237.     JZ    ENDNAME
  238.     MOV    M,A    ;PUT NAME IN FCB
  239.     LDA    QFLG    ;CAN TYPE IT IF NO QFLG
  240.     ORA    A
  241.     JZ    SKPTYP
  242.     CALL    FTYTST
  243. SKPTYP:    PUSH    B    ;SAVE CKSUM
  244.     MVI    A,ACK    ;ACK GETTING LETTER
  245.     CALL    SEND
  246.     POP    B
  247.     INX    H    ;GET NEXT CHAR
  248.     MOV    A,L    ;DON'T LET NOISE...
  249.     CPI    7FH    ;..CAUSE OVERFLOW..
  250.     JZ    GCKSER    ;..INTO PROGRAM AREA.
  251.     JMP    NAMELPG
  252. ;
  253. FTYTST:
  254.     LDA    FTYCNT
  255.     INR    A
  256.     STA    FTYCNT
  257.     CPI    9    ;ARE WE AT THE FILE TYPE?
  258.     JZ    SPCTST    ;GO IF SO
  259. ENDSPT:    MOV    A,M
  260.     CPI    ' '    ;TEST FOR SPACE
  261.     CNZ    TYPE    ;TYPE IF NOT
  262.     RET
  263. ;
  264. SPCTST:    MOV    A,M
  265.     CPI    ' '    ;TEST FOR SPACE IN FIRST FILE TYPE BYTE
  266.     RZ        ;DON'T OUTPUT PERIOD IF SPACE
  267.     MVI    A,'.'    
  268.     CALL    TYPE
  269.     JMP    ENDSPT    ;OUTPUT FIRST FILE TYPE BYTE
  270. ;
  271. ENDNAME:
  272.     LDA    QFLG
  273.     ORA    A
  274.     CNZ    CRLF
  275.     MOV    A,C    ;SEND CHECKSUM
  276.     CALL    SEND
  277.     MVI    B,1
  278.     CALL    RECV    ;CHECKSUM GOOD?
  279.     CPI    OKNMCH    ;YES IF OKNMCH SENT..
  280.     JZ    GNRET    ;..ELSE DO OVER.
  281. GCKSER:    LXI    H,FCB    ;CLEAR FCB (EXCEPT DRIVE)..
  282.     CALL    INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
  283.     CALL    ILPRTQ
  284.     DB    CR,LF,'++ Checksum error ++',CR,LF,0
  285.     CALL    HSNAK    ;DO HANDSHAKING OVER
  286.     JMP    GETNM1
  287. ;
  288. GNRET:    POP    H
  289.     RET
  290. ;
  291. HSNAK:  MVI    E,180        ;3-MINUTE MAXIMUM WAIT FOR A FILE NAME
  292. HSNAK1: CALL    CKABORT        ;WANT TO ABORT?
  293.     MVI    A,NAK        ;SEND NAK UNTIL RECEIVING ACK
  294.     CALL    SEND
  295.     MVI    B,1        ;WAIT UP TO 1 SECOND FOR A CHARACTER
  296.     CALL    RECV
  297.     CPI    ACK        ;'ACK' IS WHAT WE WERE WAITING FOR
  298.     RZ
  299.     DCR    E        ;ONE LESS TO TRY
  300.     JNZ    HSNAK1
  301.     JMP    ABORT        ;TIMED OUT, ABORT BACK TO COMMAND LINE
  302. ;
  303. TNMBUF:    MVI    A,FALSE    ;CALL FROM SENDFIL ONLY ONCE.
  304.     STA    FSTFLG
  305.     STA    FILECT
  306.     CALL    SCAN
  307.     LXI    H,NAMEBUF
  308.     SHLD    NBSAVE    ;SAVE ADDR OF 1ST NAME
  309. TNLP1:    CALL    TRTOBUF
  310.     LXI    H,FCB
  311.     LXI    D,FCBBUF
  312.     CALL    CPMLINE    ;PARSE NAME TO CP/M FORMAT
  313. TNLP2:    CALL    MFNAME    ;SEARCH FOR NAMES (* FORMAT)
  314.     JC    NEXTNM
  315.     LDA    FCB+10    ;IF CP/M 2 $SYS FILE..
  316.     ANI    80H    ;..DON'T SEND
  317.     JNZ    TNLP2
  318.     LHLD    NBSAVE    ;GET NAME
  319.     LXI    D,FCB    ;MOVE IT TO FCB
  320.     XCHG
  321.     MVI    B,12
  322.     CALL    MOVE
  323.     XCHG
  324.     SHLD    NBSAVE    ;ADDR OF NEXT NAME
  325.     LXI    H,FILECT    ;COUNT FILES FOUND
  326.     INR    M
  327.     JMP    TNLP2
  328. ;
  329. NEXTNM:    LXI    H,SNAMECT ;COUNT NAMES FOUND
  330.     DCR    M
  331.     JNZ    TNLP1
  332.     LXI    H,NAMEBUF  ;SAVE START OF BUFFER
  333.     SHLD    NBSAVE
  334.     LDA    FILECT
  335.     CPI    65    ;NO MORE THAN 64 TRANSFERS
  336.     RC
  337.     MVI    A,64    ;ONLY X'FER FIRST 64
  338.     STA    FILECT
  339.     RET
  340. ;
  341. ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
  342. ;AFTER LAST NAME
  343. ;
  344. SCAN:    PUSH    H
  345.     LXI    H,SNAMECT
  346.     MVI    M,0
  347.     LXI    H,CMDBUF+1  ;FIND END OF CMD LINE..
  348.     MOV    C,M         ;..AND PUT SPACE THERE.
  349.     MVI    B,0
  350.     LXI    H,CMDBUF+2
  351.     DAD    B
  352.     MVI    M,20H
  353.     LXI    H,CMDBUF+1
  354.     MOV    B,M
  355.     INR    B
  356.     INR    B
  357. SCANLP1:
  358.     INX    H
  359.     DCR    B
  360.     JZ    DNSCAN
  361.     MOV    A,M
  362.     CPI    20H
  363.     JNZ    SCANLP1
  364. SCANLP2:
  365.     INX    H    ;EAT EXTRA SPACES
  366.     DCR    B
  367.     JZ    DNSCAN
  368.     MOV    A,M
  369.     CPI    20H
  370.     JZ    SCANLP2
  371.     SHLD    BGNMS    ;SAVE START OF NAMES IN CMDBUF
  372.     INR    B
  373.     DCX    H
  374. SCANLP3:
  375.     INX    H
  376.     DCR    B
  377.     JZ    DNSCAN
  378.     MOV    A,M
  379.     CPI    20H
  380.     JNZ    SCANLP3
  381.     LDA    SNAMECT    ;COUNTS NAMES
  382.     INR    A
  383.     STA    SNAMECT
  384. SCANLP4:
  385.     INX    H    ;EAT SPACES
  386.     DCR    B
  387.     JZ    DNSCAN
  388.     MOV    A,M
  389.     CPI    20H
  390.     JZ    SCANLP4
  391.     JMP    SCANLP3
  392. ;
  393. DNSCAN:
  394.     MVI    M,20H    ;SPACE AFTER LAST CHAR
  395.     POP    H
  396.     RET
  397. ;
  398. ;PLACES NEXT NAME IN BUFFER SO 'CPMLINE' MAY PARSE IT
  399. ;
  400. TRTOBUF:
  401.     LHLD    BGNMS
  402.     MVI    B,0
  403.     LXI    D,FCBBUF+2
  404. TBLP:
  405.     MOV    A,M
  406.     CPI    20H
  407.     JZ    TRBFEND
  408.     STAX    D
  409.     INX    H
  410.     INX    D
  411.     INR    B    ;COUNT CHARS IN NAME
  412.     JMP    TBLP
  413. ;
  414. TRBFEND:
  415.     INX    H
  416.     MOV    A,M    ;EAT EXTRA SPACES
  417.     CPI    20H
  418.     JZ    TRBFEND
  419.     SHLD    BGNMS
  420.     LXI    H,FCBBUF+1 ;PUT # CHARS BEFORE NAME
  421.     MOV    M,B
  422.     RET
  423. ;
  424. RCVSECT:
  425.     MVI    A,1
  426.     STA    ERRCT
  427. RCVRPT: CALL    CKABORT        ;WANT TO STOP RECEIVING FILE?
  428.     LDA    QFLG
  429.     ORA    A
  430.     JZ    RCVSQ
  431.     CALL    ILPRT
  432.     DB    CR,'Awaiting # ',0
  433.     PUSH    H    ;SAVE IT
  434.     LHLD    SECTNO    ;GET SECTOR NUMBER
  435.     INX    H    ;BUMP IT
  436.     CALL    DECOUT    ;PRINT SECTOR NUMBER IN DECIMAL
  437.     CALL    ILPRT
  438.     DB    ' (', 0
  439.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  440.     CALL    ILPRT
  441.     DB    'H)',0
  442.     MOV    A,L    ;ONLY LOW BYTE USED BY PROGRAM
  443.     POP    H    ;RESTORE IT
  444. ;
  445. RCVSQ:            ;WAIT FOR SOH OR EOT
  446.     MVI    B,10    ;10 SECONDS
  447.     CALL    RECV
  448.     JC    RCVSTOT
  449.     CPI    SOH
  450.     JZ    RCVSOH
  451.     ORA    A
  452.     JZ    RCVSQ
  453.     CPI    EOT
  454.     STC
  455.     RZ
  456.     MOV    B,A
  457.     LDA    QFLG
  458.     ORA    A
  459.     JZ    RCVSERR
  460. RCVSEH:    MOV    A,B
  461.     CALL    CRLF
  462.     CALL    HEXO
  463.     CALL    ILPRT
  464.     DB    'H received not SOH - ',0
  465. RCVPRN: CALL    SHOWERR        ;DISPLAY ERROR COUNT
  466. RCVSERR:
  467.     MVI    B,1    ;WAIT FOR 1 SEC..
  468.     CALL    RECV    ;..WITH NO CHARS
  469.     JNC    RCVSERR ;LOOP UNTIL SENDER DONE
  470.     CALL    CKABORT        ;WANT TO STOP RECEIVING NOW?
  471.     LDA    CKSUMFLG    ;GET CHECKSUM FLAG
  472.     ORA    A    ;CRC IN EFFECT?
  473.     MVI    A,NAK    ;PUT NAK IN ACCUM
  474.     JNZ    RCVSER2    ;NO, SEND THE NAK
  475.     LDA    FIRSTME ;GET FIRST TIME SWITCH
  476.     ORA    A    ;HAS FIRST SOH BEEN RECEIVED?
  477.     MVI    A,NAK    ;PUT NAK IN ACCUM
  478.     JZ    RCVSER2    ;YES, THEN SEND NAK
  479.     MVI    A,CRC    ;TELL SENDER CRC IS IN EFFECT
  480. RCVSER2:
  481.     CALL    SEND    ;..THE NAK or CRC request
  482.     LDA    ERRCT    ;ABORT IF..
  483.     INR    A    ;..WE HAVE REACHED..
  484.     STA    ERRCT    ;..THE ERROR..
  485.     CPI    ERRLIM    ;..LIMIT?
  486.     JC    RCVRPT    ;..NO, TRY AGAIN
  487.     LDA    QFLG
  488.     ORA    A
  489.     JZ    RCVSABT
  490. RCVCKQ:    CALL    CKQUIT
  491.     JZ    RCVSECT
  492. RCVSABT:
  493.     LXI    SP,STACK    ;RESET THE STACK JUST IN CASE
  494.     CALL    CLOSFIL        ;CLOSE THE PARTIAL FILE
  495.     CALL    NOASK        ;DELETE PARTIAL FILE
  496.     CALL    ILPRT
  497.     DB    CR,LF,LF
  498.     DB    '++ File receive cancelled and unfinished file deleted ++'
  499.     DB    BELL,CR,LF,0
  500.     JMP    DONETCA
  501. ;
  502. RCVSTOT:
  503.     LDA    QFLG
  504.     ORA    A
  505. RCVSPT:    CALL    ILPRT
  506.     DB    CR,LF,'++ Timeout ',0
  507.     CALL    SHOWERR
  508. RCVSCRC:
  509.     CALL    RCVSCRC2
  510.     JMP    RCVSERR
  511. ;
  512. ;ROUTINE WILL SWITCH FROM CRC TO CHECKSUM IF ERCNT REACHES ERRCRC
  513. ;AND FIRSTME IS TRUE
  514. ;
  515. RCVSCRC2:
  516.     LDA    ERRCT
  517.     CPI    ERRCRC
  518.     RNZ
  519.     LDA    FIRSTME
  520.     ORA    A
  521.     RZ
  522.     LDA    CKSUMFLG
  523.     ORA    A
  524.     RNZ
  525.     CMA
  526.     STA    CKSUMFLG
  527.     STA    CKSUMDFLT
  528.     CALL    ILPRTQ
  529.     DB    '++ Switching to Checksum mode ++',CR,LF
  530.     DB    '++ Sender may not be CRC capable ++',CR,LF,BELL,0
  531.     RET
  532. ;
  533. ;Got SOH - get block #, block # complemented
  534. ;
  535. RCVSOH:    XRA    A    ;ZERO ACCUM
  536.     STA    FIRSTME ;INDICATE FIRST SOH RECV'D
  537.     MVI    B,1    ;TIMEOUT = 1 SEC
  538.     CALL    RECV    ;GET SECTOR
  539.     JC    RCVSTOT ;GOT TIMEOUT
  540.     MOV    D,A
  541.     MVI    B,1
  542.     CALL    RECV
  543.     JC    RCVSTOT
  544.     CMA
  545.     CMP    D
  546.     JZ    RCVDATA
  547.     LDA    QFLG
  548.     ORA    A
  549.     JZ    RCVSERR
  550. RCVBSE:
  551.     CALL    ILPRT
  552.     DB    CR,LF,'++ Bad sector # in Header ',0
  553.     JMP    RCVPRN
  554. ;
  555. RCVDATA:
  556.     MOV    A,D
  557.     STA    RCVSNO
  558.     MVI    A,1
  559.     STA    DATAFLG
  560.     MVI    C,0
  561.     CALL    CLRCRC    ;CLEAR CRC COUNTER
  562.     LXI    H,80H
  563. RCVCHR:
  564.     MVI    B,1
  565.     CALL    RECV
  566.     JC    RCVSTOT
  567.     MOV    M,A
  568.     INR    L
  569.     JNZ    RCVCHR
  570.     LDA    CKSUMFLG
  571.     ORA    A
  572.     JZ    RCVCRC
  573.     MOV    D,C
  574.     XRA    A
  575.     STA    DATAFLG
  576.     MVI    B,1
  577.     CALL    RECV
  578.     JC    RCVSTOT
  579.     CMP    D
  580.     JNZ    RCVCERR
  581. CHKSNUM:
  582.     LDA    RCVSNO
  583.     MOV    B,A
  584.     LDA    SECTNO
  585.     CMP    B
  586.     JZ    RECVACK
  587.     INR    A
  588.     CMP    B
  589.     JNZ    ABORT
  590.     RET
  591. ;
  592. RCVCRC:
  593.     MVI    E,2    ;NUMBER OF CRC BYTES
  594. RCVCRC2:
  595.     MVI    B,1
  596.     CALL    RECV
  597.     JC    RCVSTOT
  598.     DCR    E
  599.     JNZ    RCVCRC2
  600.     CALL    CHKCRC
  601.     ORA    A
  602.     JZ    CHKSNUM
  603.     LDA    QFLG
  604.     ORA    A
  605.     JZ    RCVSERR
  606. RCVCRER:
  607.     CALL    ILPRT
  608.     DB    CR,LF,'++ CRC error ',0
  609.     JMP    RCVPRN
  610. ;
  611. RCVCERR:
  612.     LDA    QFLG
  613.     ORA    A
  614.     JZ    RCVSERR
  615. RCVCPR:
  616.     CALL    ILPRT
  617.     DB    CR,LF,'++ Checksum error ',0
  618.     JMP    RCVPRN
  619. ;
  620. RECVACK:
  621.     CALL    SENDACK
  622.     JMP    RCVSECT
  623. ;
  624. SENDACK:
  625.     MVI    A,ACK
  626.     CALL    SEND
  627.     RET
  628. ;
  629. SENDHDR:
  630.     LDA    QFLG
  631.     ORA    A
  632.     JZ    SENDHNM
  633.     CALL    ILPRT
  634.     DB    CR,'Sending # ',0
  635.     PUSH    H
  636.     LHLD    SECTNO    ;GET SECTOR NUMBER
  637.     CALL    DECOUT    ;PRINT IT IN DECIMAL
  638.     CALL    ILPRT
  639.     DB    ' (',0
  640.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  641.     CALL    ILPRT
  642.     DB    'H)',0
  643.     POP    H
  644. SENDHNM:
  645.     MVI    A,SOH
  646.     CALL    SEND
  647.     LDA    SECTNO
  648.     CALL    SEND
  649.     LDA    SECTNO
  650.     CMA
  651.     CALL    SEND
  652.     RET
  653. ;
  654. SENDSEC:
  655.     MVI    A,1
  656.     STA    DATAFLG
  657.     MVI    C,0
  658.     CALL    CLRCRC
  659.     LXI    H,80H
  660. SENDC:
  661.     MOV    A,M
  662.     CALL    SEND
  663.     INR    L
  664.     JNZ    SENDC
  665.     XRA    A
  666.     STA    DATAFLG
  667.     RET
  668. ;
  669. SENDCKS:
  670.     MOV    A,C
  671.     CALL    SEND
  672.     RET
  673. ;
  674. SENDCRC:
  675.     CALL    FINCRC
  676.     MOV    A,D
  677.     CALL    SEND
  678.     MOV    A,E
  679.     CALL    SEND
  680.     XRA    A
  681.     RET
  682. ;
  683. ;
  684. ;After a record is sent, a character is returned telling if it was re-
  685. ;ceived properly or not.  An ACK allows the next record to be sent.  A
  686. ;NAK sends an error message and the current record is again repeated.
  687. ;This occurs until the error limit has been reached.  If the first NAK
  688. ;is missed, it waits up to 12 seconds before declaring a 2nd error.
  689. ;This insures there is no collision with the station attempting to send
  690. ;the NAK, since it waits only 10 seconds.
  691. ;
  692. GETACK:    MVI    B,12        ;12 SECONDS
  693.     CALL    RECVDG        ;WAIT FOR ACK OR NAK
  694.     JC    GETATOT        ;NO CHARACTER, TIMED OUT
  695.     CPI    ACK
  696.     RZ            ;IF ACK RETURN AND SEND NEXT RECORD
  697. ;
  698. ;If the ACKNAK option is FALSE it will resend the sector when any char-
  699. ;acter other than ACK is received (including NAK).
  700. ;
  701.     MOV    B,A
  702.     LDA    NAKONLY
  703.     ORA    A
  704.     JZ    ALLOTH
  705.     CPI    NAK        ;WAS IT AN AUTHENTIC 'NAK'?
  706.     JNZ    GETACK        ;IGNORE IF NEITHER 'ACK' NOR 'NAK'
  707.                 ;WILL EVENTUALLY TIME OUT
  708. ALLOTH:    LDA    QFLG
  709.     ORA    A
  710.     JZ    ACKERR
  711.     CALL    ILPRT
  712.     DB    CR,LF,'++ ',0
  713.     MOV    A,B
  714.     CPI    NAK        ;IS IT A 'NAK'?
  715.     JZ    GETACK2        ;SHOW 'NAK' IN THAT CASE
  716.     CALL    HEXO
  717.     MVI    A,'H'
  718.     CALL    TYPE
  719.     JMP    GETACK3
  720. GETACK2:
  721.     CALL    ILPRT
  722.     DB    'NAK',0    
  723. GETACK3:
  724.     CALL    ILPRT        ;PRINT THE ERROR MESSAGE
  725.     DB    ' received not ACK - ',0
  726.     CALL    SHOWERR        ;SHOW THE ERROR NUMBER
  727. ACKERR:    LDA    ERRCT
  728.     INR    A
  729.     STA    ERRCT
  730.     DCR    A
  731.     CPI    ERRLIM
  732.     RC
  733.     LDA    QFLG
  734.     ORA    A
  735.     JZ    CSABORT
  736. GACKV:    CALL    CKQUIT
  737.     STC
  738.     RZ
  739. CSABORT:
  740.     CALL    ERXIT
  741.     DB    CR,LF,'Can''t send sector -- Aborting',CR,LF,'$'
  742. GETATOT:
  743.     LDA    QFLG
  744.     ORA    A
  745.     JZ    ACKERR
  746.     CALL    ILPRT
  747.     DB    CR,LF,'++ Timeout on ACK - ',0
  748.     CALL    SHOWERR        ;DISPLAY ERROR COUNT
  749.     JMP    ACKERR
  750. ;
  751. CKABORT:
  752.     LDA    QFLG
  753.     ORA    A
  754.     RZ
  755. CKABGO:    CALL    STAT
  756.     RZ
  757.     CALL    KEYIN
  758.     CPI    CAN
  759.     RNZ
  760. ABORT:    LXI    SP,STACK
  761. ABORTL:    MVI    B,1
  762.     CALL    RECV
  763.     JNC    ABORTL
  764.     MVI    A,CAN
  765.     CALL    SEND
  766. ABORTW:    MVI    B,1
  767.     CALL    RECV
  768.     JNC    ABORTW
  769.     MVI    A,' '
  770.     CALL    SEND
  771.     MVI    A,'B'     ;TURN MULTI-FILE MODE..
  772.     STA    BATCHFLG  ;..OFF SO ROUTINE ENDS.
  773.     LDA    OPTION        ;RECEIVING A FILE NOW?
  774.     CPI    'R'
  775.     JZ    RCVSABT        ;IF YES, CANCEL THE UNFINISHED FILE
  776.     CALL    ILPRT
  777.      DB    CR,LF,LF,'++ File send cancelled ++',CR,LF,BELL,0
  778.     JMP    DONETCA
  779. ;
  780. INCRSNO:
  781.     PUSH    H
  782.     LHLD    SECTNO    ;GET SECTOR NUMBER
  783.     INX    H    ;BUMP IT
  784.     SHLD    SECTNO    ;STORE IT
  785.     MOV    A,L
  786.     POP    H
  787.     RET
  788. ;
  789. ;---->    RECV: Receive a character
  790. ;
  791. ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
  792. ;characters on the line. For example, having just sent a sector, calling
  793. ;RECVDG will delete any line noise induced characters LONG before the
  794. ;ACK/NAK would be received.
  795. ;
  796. RECVDG: CALL    CKMODM        ;CATCH ANY GARBAGE CHARACTERS
  797. RECV:    PUSH    D
  798. MSEC:    PUSH    H
  799.     LXI    H,7500
  800.     CALL    FIXCNT
  801.     PUSH    H
  802.     POP    D
  803.     POP    H
  804.     CALL    CKABORT
  805. MWTI:
  806.     CALL    RCVREADY
  807.     JZ    MCHAR
  808.     DCR    E
  809.     JNZ    MWTI
  810.     DCR    D
  811.     JNZ    MWTI
  812.     DCR    B
  813.     JNZ    MSEC
  814.     POP    D
  815.     STC
  816.     RET
  817. ;
  818. MCHAR:
  819. MCHAR1:
  820.     CALL    IN$MODDATP
  821.     POP    D
  822.     PUSH    PSW
  823.     CALL    UPDCRC      ;CALCULATE CRC
  824.     ADD    C    
  825.     MOV    C,A
  826.     LDA    RSEEFLG
  827.     ORA    A
  828.     JZ    MONIN
  829.     LDA    VSEEFLG
  830.     ORA    A
  831.     JNZ    NOMONIN
  832.     LDA    DATAFLG
  833.     ORA    A
  834.     JZ    NOMONIN
  835. MONIN:    POP    PSW
  836.     PUSH    PSW
  837.     CALL    SHOW
  838. NOMONIN:
  839.     POP    PSW
  840.     ORA    A
  841.     RET
  842. ;
  843. SEND:    PUSH    PSW
  844.     LDA    SSEEFLG
  845.     ORA    A
  846.     JZ    MONOUT
  847.     LDA    VSEEFLG
  848.     ORA    A
  849.     JNZ    NOMONOT
  850.     LDA    DATAFLG
  851.     ORA    A
  852.     JZ    NOMONOT
  853. MONOUT:    POP    PSW
  854.     PUSH    PSW
  855.     CALL    SHOW
  856. NOMONOT:
  857.     POP    PSW
  858.     PUSH    PSW
  859.     CALL    UPDCRC    ;CALCULATE CRC
  860.     ADD    C
  861.     MOV    C,A
  862. SENDW:    CALL    SENDREADY
  863.     JNZ    SENDW
  864.     POP    PSW
  865.     CALL    OUT$MODDATP
  866.     RET
  867. ;
  868. WAITNAK:
  869.     CALL    ILPRTQ
  870.     DB    'Awaiting initial NAK',CR,LF,0
  871. WAITNLP:
  872.     CALL    CKABORT
  873.     MVI    B,1
  874.     CALL    RECV
  875.     CPI    NAK
  876.     RZ
  877.     CPI    CRC    ;CRC REQUEST?
  878.     JZ    WAITCRC    ;YES, GO SET CRC FLAG
  879.     CPI    CAN
  880.     JZ    ABORT
  881.     DCR    E
  882.     JZ    ABORT
  883.     JMP    WAITNLP
  884. ;
  885. WAITCRC:
  886.     CALL    ILPRTQ
  887.     DB    'CRC request received',CR,LF,0
  888.     XRA    A
  889.     STA    CKSUMFLG
  890.     RET
  891. ;
  892. ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
  893. ;NO QUESTIONS ASKED, JUST QUIT
  894. ;
  895. CKQUIT:
  896.     LDA    BATCHFLG
  897.     ORA    A
  898.     JNZ    CKQTASK    ;ASK FOR RETRY
  899.     INR    A    ;RESET ZERO FLG
  900.     RET
  901. ;
  902. CKQTASK:
  903.     MVI    A,1
  904.     STA    ERRCT
  905.     CALL    ILPRT
  906.     DB    CR,LF,'Multiple errors encountered.',CR,LF
  907.     DB    'Type Q to quit, R to retry:  ',BELL,0
  908.     CALL    KEYIN
  909.     PUSH    PSW
  910.     CALL    CRLF
  911.     POP    PSW
  912.     CALL    UCASE    ;INSTEAD OF "ANI 5FH"
  913.     CPI    'R'
  914.     RZ
  915.     CPI    'Q'
  916.     JNZ    CKQUIT
  917.     ORA    A
  918.     RET
  919. ;
  920. ;Get the error count and display on CRT
  921. ;
  922. SHOWERR:
  923.     PUSH    H        ;SAVE THE CURRENT ADDRESS
  924.     LHLD    ERRCT        ;GET THE CURRENT ERROR NUMBER
  925.     MVI    H,0        ;ONLY A 8-BIT NUMBER, NOW IN 'L' REG.
  926.     CALL    DECOUT        ;DISPLAY THE ERROR IN DECIMAL
  927.     POP    H        ;RESTORE THE CURRENT ADDRESS
  928.     CALL    ILPRT
  929.     DB    ' ++',CR,LF,0    ;FINISH THE ERROR MESSAGE
  930.     RET
  931. ;
  932. ERXIT:    POP    D
  933.     CALL    PRTMSG
  934.     MVI    A,BELL
  935.     CALL    TYPE
  936.     LDA    BATCHFLG
  937.     ORA    A
  938.     JNZ    DONETCA
  939.     MVI    A,'Q'    ;RESET QFLG
  940.     STA    QFLG
  941.     JMP    ABORT    ;ABORT OTHER COMPUTER
  942. ;
  943. DONE:    LDA    BATCHFLG
  944.     ORA    A
  945.     JNZ    DONETC
  946.     LDA    QFLG
  947.     ORA    A
  948.     JZ    NMSTRNS
  949.     MVI    B,12        ;ZERO OUT FTRNMSG
  950.     LXI    H,FTRNMSG
  951.     MVI    A,0
  952. ZEROLP:    MOV    M,A
  953.     INX    H
  954.     DCR    B
  955.     JNZ    ZEROLP
  956.     MVI    B,12        ;PUT FILE NAME IN FTRNMSG
  957.     LXI    H,FCB+1        
  958.     LXI    D,FTRNMSG
  959. LOADMSG:
  960.     MVI    A,4    ;START OF FILE TYPE?
  961.     CMP    B
  962.     JZ    PERIOD    ;PUT IN PERIOD IF SO
  963.     MOV    A,M    
  964.     CPI    ' '    ;DON'T PUT IN SPACE
  965.     JZ    SKPSP    
  966.     STAX    D    ;STORE IN FTRNMSG
  967.     INX    D
  968. SKPSP:    INX    H
  969.     DCR    B
  970.     MOV    A,B
  971.     ORA    A        ;END OF FILE NAME?
  972.     JZ    FTRNMSG0    ;DISPLAY FILE NAME
  973.     JMP    LOADMSG        ;LOOP FOR ANOTHER CHARACTER
  974. ;
  975. PERIOD:
  976.     MOV    A,M
  977.     CPI    ' '        ;IS FILE TYPE EMPTY?
  978.     JZ    FTRNMSG0    ;GO IF SO
  979.     MVI    A,'.'        ;ELSE PUT PERIOD IN MESSAGE
  980.     STAX    D
  981.     INX    D
  982.     DCR    B
  983.     JMP    LOADMSG    
  984. ;
  985. FTRNMSG0:
  986.     CALL    ILPRT
  987.     DB    CR,LF
  988. FTRNMSG:
  989.     DS    12
  990.     DB    0
  991.     CALL    ILPRT
  992.     DB    ' Transferred',CR,LF,LF,0
  993. NMSTRNS:
  994.     LDA    FCB    ;SAVE DRIVE NO.
  995.     STA    DISKNO
  996.     LXI    H,FCB    ;BLANK OUT FILE CONTROL BLOCKS
  997.     CALL    INITFCBS
  998.     LDA    DISKNO    ;PUT DRIVE NUMBER BACK
  999.     STA    FCB
  1000.     LXI    H,RESTSN ;RESTORE SECTORE NUMBERS..
  1001.     LXI    D,SECTNOB ;..FOR NEW FILE TRANSFER.
  1002.     MVI    B,SECTNOE-SECTNOB ;ROUTINE ALSO DONE IN MENU.
  1003.     CALL    MOVE
  1004.     CALL    CKMODM        ;CATCH ANY GARBAGE CHARACTERS
  1005.     LDA    SENDFLG    ;GOES TO EITHER SEND OR..
  1006.     ORA    A    ;..RECEIVE FILE, DEPENDING..
  1007.     JNZ    SENDFIL1    ;..UPON WHICH ROUTINE SET..
  1008.     JMP    RCVFIL1    ;..THE FLAG IN MULTI-FILE MODE.
  1009. ;
  1010. DONETC: CALL    CKABORT        ;SLIGHT DELAY FOR NEXT MESSAGE
  1011.     CALL    ILPRT
  1012.     DB    CR,LF,'All transfers completed',CR,LF,BELL,0
  1013. DONETCA:
  1014.     MVI    A,TRUE
  1015.     STA    FIRSTME    ;SET FIRST-TIME FLAG
  1016.     STA    FSTFLG    ;RESET MULTIFILE TRANS
  1017.     STA    NFILFLG    ;..USED IN TERMINAL ROUTINE
  1018.     CMA
  1019.     STA    SAVEFLG    ;STOP MEMORY SAVE IN TERM ROUTINE
  1020.     STA    LISTMOR    ;STOP ANY BUFFERED OUTPUT TO PRINTER
  1021.     LXI    H,BOTTRAM    ;RESET PRINTER BUFFER POINTERS
  1022.     SHLD    HLSAVE1
  1023.     SHLD    HLSAVE2
  1024.     LDA    TERMFLG    ;SEE IF RETURN TO..
  1025.     ORA    A    ;..TERMINAL MODE..
  1026.     JNZ    MENU    ;..AFTER X'FER.
  1027.     CALL    ILPRT
  1028.     DB    CR,LF,'** Entering terminal mode **',CR,LF,LF,BELL,0
  1029.     JMP    TERM
  1030. ;
  1031. ;Shows the time to transfer a file at various baud rates
  1032. ;
  1033. SENDTIM:
  1034.     CALL    ILPRT            ;PRINT:
  1035.     DB    'File open:  ',0
  1036.     LHLD    RCNT        ;GET RECORD COUNT.
  1037.     CALL    DECOUT        ;PRINT DECIMAL NUMBER OF RECORDS
  1038.     CALL    ILPRT
  1039.     DB    ' (',0
  1040.     CALL    DHXOUT        ;NOW PRINT SIZE IN HEX.
  1041.     CALL    ILPRT
  1042.     DB    ' Hex) Records',CR,LF
  1043.     DB    'Send time:  ',0
  1044.     LDA    MSPEED        ;GET THE SPEED INDICATOR
  1045.     MVI    D,0
  1046.     MOV    E,A        ;SET UP FOR TABLE ACCESS
  1047.     LXI    H,BTABLE    ;POINT TO BAUD FACTOR TABLE
  1048.     DAD    D        ;INDEX TO PROPER FACTOR
  1049.     DAD    D
  1050.     MOV    E,M        ;FACTOR IN DE
  1051.     INX    H
  1052.     MOV    D,M
  1053.     LHLD    RCNT        ;GET # OF RECORDS
  1054.     CALL    DIVHLDE        ;DIVIDE HL BY VALUE IN A (RECORDS/MIN)    
  1055.     PUSH    H
  1056.     MOV    L,C
  1057.     MOV    H,B
  1058.     CALL    DECOUT        ;PRINT THE MINUTES PORTION
  1059.     CALL    ILPRT
  1060.     DB    ' mins, ',0
  1061.     LXI    H,SECTBL    ;POINT TO DIVISORS FOR SECONDS
  1062.     LXI    D,0        ;   CALCULATION
  1063.     LDA    MSPEED        ;GET INDEX FOR BAUD RATE
  1064.     MOV    E,A
  1065.     DAD    D        ;INDEX INTO TABLE
  1066.     MOV    A,M        ;GET MULTIPLIER = (SEC/REC) x 16
  1067.     POP    H        ;GET REMAINDER
  1068.     CALL    MULHLA        ;MULTIPLY THE 'HL' x 'A'
  1069.     CALL    SHFTHL        ;DIVIDE BY 16
  1070.     CALL    SHFTHL
  1071.     CALL    SHFTHL
  1072.     CALL    SHFTHL    
  1073.     MVI    H,0
  1074.     CALL    DECOUT        ;PRINT THE SECONDS PORTION
  1075.     CALL    ILPRT
  1076.     DB    ' secs at ',0
  1077.     CALL    BAUDPRT
  1078.     CALL    ILPRT
  1079.         DB    'To cancel use ctrl-X',CR,LF,0
  1080.     RET
  1081. ;
  1082. BTABLE:    DW    5,13,19,25,29,48,96,192,384,0    ;RECORDS/MIN FOR 110-9600 BAUD
  1083. SECTBL:    DB    192,74,51,38,33,20,11,5,3,0
  1084. ;
  1085. ;    
  1086. ;---->  DIVHLDE: DIVIDES 'HL' BY VALUE IN 'DE', 
  1087. ;    UPON EXIT: 'BC'=QUOTIENT,'L'=REMAINDER
  1088. ;
  1089. DIVHLDE:
  1090.     PUSH    D        ;SAVE DIVISOR
  1091.     MOV    A,E
  1092.     CMA            ;NEGATE DIVISOR
  1093.     MOV    E,A
  1094.     MOV    A,D
  1095.     CMA
  1096.     MOV    D,A
  1097.     INX    D        ;DE IS NOW TWOS COMPLEMENTED
  1098.     LXI    B,0        ;INITIATE QUOTIENT
  1099. DIVL1:    DAD    D        ;SUBTRACT DIVISOR FROM DIVIDEND
  1100.     INX    B        ;INCREASE QUOTIENT
  1101.     JC    DIVL1        ;LOOP UNTIL SIGN CHANGES
  1102.     DCX    B        ;ADJUST QUOTIENT
  1103.     POP    D        ;RETRIEVE DIVISOR
  1104.     DAD    D        ;ADJUST REMAINDER
  1105.     RET
  1106.  
  1107. ;
  1108. ;---->  MULHLA:  MULTIPLY THE VALUE IN 'HL' BY THE VALUE IN 'A'
  1109. ;            RETURN WITH ANSWER IN 'HL'
  1110. ;
  1111. MULHLA:    XCHG            ;MULTIPLICAND TO DE
  1112.     LXI    H,0        ;INITIALIZE PRODUCT
  1113.     INR    A        ;ADJUST MULTIPLIER
  1114. MULLP:    DCR    A
  1115.     RZ
  1116.     DAD    D
  1117.     JMP    MULLP
  1118. ;
  1119. ;  SHIFT 'HL' REGISTER PAIR ONE BIT TO THE RIGHT
  1120. ;
  1121. SHFTHL:    ORA    A    ;CLEAR THE CARRY
  1122.     MOV    A,H
  1123.     RAR
  1124.     MOV    H,A
  1125.     MOV    A,L
  1126.     RAR        ;PUT CARRY INTO HIGH BIT
  1127.     MOV    L,A
  1128.     RET
  1129. ;
  1130. ;****************************************************************
  1131. ;*                                *
  1132. ;*   CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20    *
  1133. ;*   8080 Mnemonics                        *
  1134. ;*                                *
  1135. ;*     These subroutines will compute and check a true 16-bit    *
  1136. ;*   Cyclic Redundancy Code for a message of arbitrary length.    *
  1137. ;*                                *
  1138. ;*     The use of this scheme will guarantee detection of all    *
  1139. ;*   single and double bit errors, all  errors  with  an  odd    *
  1140. ;*   number  of  error bits, all burst errors of length 16 or    *
  1141. ;*   less, 99.9969% of all 17-bit error bursts, and  99.9984%    *
  1142. ;*   of  all  possible  longer  error bursts.  (Ref: Computer    *
  1143. ;*   Networks, Andrew S.  Tanenbaum, Prentiss-Hall, 1981)    *
  1144. ;*                                *
  1145. ;*   Designed & coded by Paul Hansknecht, June 13, 1981        *
  1146. ;*                                *
  1147. ;*   Copyright (c) 1981, Carpenter Associates            *
  1148. ;*            Box 451                    *
  1149. ;*            Bloomfield Hills, MI 48013            *
  1150. ;*            313/855-3074                *
  1151. ;*                                *
  1152. ;*   This program may be freely reproduced for non-profit use.    *
  1153. ;*                                *
  1154. ;****************************************************************
  1155. ;
  1156. ;    ENTRY    CLRCRC,UPDCRC,FINCRC,CHKCRC
  1157. ;
  1158. CLRCRC:    EQU    $    ;RESET CRC ACCUMULATOR FOR A NEW MESSAGE.
  1159.     PUSH    H
  1160.     LXI    H,0
  1161.     SHLD    CRCVAL
  1162.     POP    H
  1163.     RET
  1164. ;
  1165. UPDCRC:    EQU    $    ;UPDATE CRC ACCUMULATOR USING BYTE IN (A).
  1166.     PUSH    PSW
  1167.     PUSH    B
  1168.     PUSH    H
  1169.     MVI    B,8
  1170.     MOV    C,A
  1171.     LHLD    CRCVAL
  1172. UPDLOOP:
  1173.     MOV    A,C
  1174.     RLC
  1175.     MOV    C,A
  1176.     MOV    A,L
  1177.     RAL
  1178.     MOV    L,A
  1179.     MOV    A,H
  1180.     RAL
  1181.     MOV    H,A
  1182.     JNC    SKIPIT
  1183.     MOV    A,H    ;THE GENERATOR IS X^16 + X^12 + X^5 + 1
  1184.     XRI    10H    ;AS RECOMMENDED BY CCITT.
  1185.     MOV    H,A    ;AN ALTERNATE GENERATOR WHICH IS OFTEN
  1186.     MOV    A,L    ;USED IN SYNCHRONOUS TRANSMISSION PROTOCOLS
  1187.     XRI    21H    ;IS X^16 + X^15 + X^2 + 1. THIS MAY BE
  1188.     MOV    L,A    ;USED BY SUBSTITUTING XOR 80H FOR XOR 10H
  1189. SKIPIT:    DCR    B    ;AND XOR 05H FOR XOR 21H IN THE ADJACENT CODE
  1190.     JNZ    UPDLOOP
  1191.     SHLD    CRCVAL
  1192.     POP    H
  1193.     POP    B
  1194.     POP    PSW
  1195.     RET
  1196. ;
  1197. FINCRC:    EQU    $    ;FINISH CRC CALCULATION FOR OUTPUT MESSAGE
  1198.     PUSH    PSW
  1199.     XRA    A
  1200.     CALL    UPDCRC
  1201.     CALL    UPDCRC
  1202.     PUSH    H
  1203.     LHLD    CRCVAL
  1204.     MOV    D,H
  1205.     MOV    E,L
  1206.     POP    H
  1207.     POP    PSW
  1208.     RET
  1209. ;
  1210. CHKCRC:    EQU    $    ;CHECK CRC BYTES OF RECEIVED MESSAGE
  1211.     PUSH    H
  1212.     LHLD    CRCVAL
  1213.     MOV    A,H
  1214.     ORA    L
  1215.     POP    H
  1216.     RZ
  1217.     MVI    A,0FFH
  1218.     RET
  1219. ;
  1220. CRCVAL:
  1221.     DW    0
  1222. ;
  1223. ;
  1224.     LINK    FILES
  1225. ;USH    H
  1226.     LXI    H,0
  1227.     SHLD    CRCVAL
  1228.     POP    H
  1229.     RET
  1230. ;
  1231. UPDCRC:    EQU    $    ;UPDATE CRC ACCUMULATOR USING BYTE IN (