home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / os968ka / k6opt2.asm < prev    next >
Assembly Source File  |  2020-01-01  |  30KB  |  555 lines

  1.           nam       Kermit68K
  2.           ttl       Low-level protocol subroutines module
  3.  
  4. *         Kermit68K: source file K68PT2
  5. *
  6. * Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
  7. * Bologna University, Physics Department, July 1987.
  8. *
  9. * All rights reserved to Bologna University, Italy.
  10. *
  11. * Permission is granted to any individual or institution
  12. * to use, copy, or redistribute this software so long as
  13. * it  is not  sold for  profit, provided  this copyright
  14. * notice is retained.
  15. *
  16. * Modification History:
  17. *
  18. * Version  Date    Who              Comments
  19. *
  20. * 1.0.00   870701  Roberto Bagnara  First official release
  21.  
  22.           use       DefsFile
  23.  
  24. Edition   equ       0
  25.           psect     K68ProtoFuncs2,0,0,Edition,0,0
  26.  
  27. ******************************* TrnsInit ******************************ok
  28. *                                                                     *
  29. *  Initialize a transaction.                                          *
  30. *                                                                     *
  31. *         Entry conditions : none                                     *
  32. *                                                                     *
  33. *         Exit  conditions : none                                     *
  34. *                                                                     *
  35. ***********************************************************************
  36. TrnsInit: MOVE.B    #1,BlChkUs(A6)     Reset block check type to 1
  37.           SF        Bit8Flag(A6)       Reset 8th bit quoting stuff
  38.           MOVE.B    #1,NextPckN(A6)    Reset packet counters
  39.           MOVE.B    #0,PackNum(A6)
  40.           MOVE.B    #-1,PrevPckN(A6)
  41.           SF        MStrFlag(A6)       Reset memory string flag
  42.           CLR.L     MStrgPnt(A6)       Reset memory string pointer
  43.           SF        CtlXSeen(A6)       Reset interrupts flag
  44.           SF        CtlZSeen(A6)
  45.           CLR.B     SendBuf(A6)        Clear send buffer
  46.           CLR.B     FilName(A6)        Clear current file name
  47.           MOVE.B    RtryInit(A6),Retry(A6) Initialize the retry limit
  48.           CLR.L     ChrsSent(A6)       Clear the statistic variables
  49.           CLR.L     ChrsRecd(A6)
  50.           CLR.L     DChsSent(A6)
  51.           CLR.L     DChsRecd(A6)
  52.           CLR.L     PcksSent(A6)
  53.           CLR.L     PcksRecd(A6)
  54.           CLR.L     NAKsSent(A6)
  55.           CLR.L     NAKsRecd(A6)
  56.           RTS
  57.  
  58. *********************************** SetGCmd ***************************ok
  59. *                                                                     *
  60. *  Setup for generic commands.                                        *
  61. *                                                                     *
  62. *         Entry conditions : D0.B command type                        *
  63. *                            A0.L destroyed                           *
  64. *                            A1.L destroyed                           *
  65. *                            A2.L first  argument address, if any     *
  66. *                            A3.L second argument address, if any     *
  67. *                            A4.L third  argument address, if any     *
  68. *                                                                     *
  69. *         Exit  conditions : D0.L destroyed                           *
  70. *                                                                     *
  71. ***********************************************************************
  72. SetGCmd:  LEA       CmdBuf(A6),A1      Load pointer to command buffer
  73.           MOVE.B    D0,(A1)+           Write command type
  74.           CLR.B     (A1)               Terminate it
  75.           MOVE.L    A2,D0              First argument pointer null ?
  76.           BEQ.S     SetGCmd1           Yes, exit
  77.           TST.B     (A2)               No, first argument null ?
  78.           BEQ.S     SetGCmd1           Yes, exit
  79.           MOVEA.L   A2,A0              Load pointer to first argument
  80.           BSR       CpStrLn            Copy it to data buffer
  81.           MOVE.L    A3,D0              Second argument pointer null ?
  82.           BEQ.S     SetGCmd1           Yes, exit
  83.           TST.B     (A3)               No, second argument null ?
  84.           BEQ.S     SetGCmd1           Yes, exit
  85.           MOVEA.L   A3,A0              Load pointer to second argument
  86.           BSR       CpStrLn            Copy it to data buffer
  87.           MOVE.L    A4,D0              Third argument pointer null ?
  88.           BEQ.S     SetGCmd1           Yes, exit
  89.           TST.B     (A4)               No, third argument null ?
  90.           BEQ.S     SetGCmd1           Yes, exit
  91.           MOVEA.L   A4,A0              Load pointer to third argument
  92.           BSR       CpStrLn            Copy it to data buffer
  93. SetGCmd1  MOVE.B    #'G',ServrCmd(A6)  Generic command packet type
  94.           BSR       TrnsInit           Initialize the transaction
  95.           RTS
  96.  
  97. ********************************* Decode ******************************ok
  98. *                                                                     *
  99. *  Kermit packet decoding procedure, decodes from DataBuf and call an *
  100. *  output function at the given address.                              *
  101. *                                                                     *
  102. *         Entry conditions : A0.L address of the output function      *
  103. *                                                                     *
  104. *         Exit  conditions : D0.B completion code                     *
  105. *                                                                     *
  106. ***********************************************************************
  107. Decode:   MOVEM.L   A1/D1-D3,-(A7)     Save working registers
  108.           LEA       DataBuf(A6),A1     Pointer to data buffer
  109. Decode1   MOVEQ     #1,D3              Setup the repeat counter
  110.           MOVE.B    (A1)+,D0           Get a character
  111.           BEQ.S     Decode9            Exit at end of buffer
  112.           TST.B     ReptFlag(A6)       Repeat processing ?
  113.           BEQ.S     Decode2            No
  114.           CMP.B     ReptQuot(A6),D0    Yes, got a repeat prefix ?
  115.           BNE.S     Decode2            No
  116.           MOVE.B    (A1)+,D3           Yes, get the repeat count
  117.           SUBI.B    #32,D3             Convert it ...
  118.           MOVE.B    (A1)+,D0           ... and get the prefixed character
  119. Decode2   MOVEQ     #$00,D1            Clear the 8th bit register
  120.           TST.B     Bit8Flag(A6)       8th bit prefixing ?
  121.           BEQ.S     Decode3            No
  122.           CMP.B     Bit8Quot(A6),D0    Yes, got an 8th bit prefix ?
  123.           BNE.S     Decode3            No
  124.           MOVEQ     #$80,D1            Yes, remember this ...
  125.           MOVE.B    (A1)+,D0           ... and get the prefixed character
  126. Decode3   CMP.B     ICtlQuot(A6),D0    Got a control prefix ?
  127.           BNE.S     Decode6            No
  128.           MOVE.B    (A1)+,D0           Yes, get its operand
  129.           MOVE.B    D0,D2              Make a copy
  130.           ANDI.B    #$7F,D2            Only look at lower 7 bits
  131.           CMPI.B    #$40,D2            Above Null ?
  132.           BLT.S     Decode4            No, look for Delete
  133.           CMPI.B    #$5F,D2            Yes, between Null and US ?
  134.           BLE.S     Decode5            Yes, uncontrollify
  135. Decode4   CMPI.B    #'?',D2            Delete ?
  136.           BNE.S     Decode6            No, character not in control range
  137. Decode5   EORI.B    #64,D0             Uncontrollify
  138. Decode6   OR.B      D1,D0              OR in the 8th bit
  139.           TST.B    Binary(A6)          Are we in binary mode ?
  140.           BNE.S    Decode8             Yes, CRLF-nl mapping not needed
  141.           CMPI.B   #Asc_CR,D0          Carriage Return ?
  142.           BEQ.S    Decode1             Yes, discard it
  143.           CMPI.B   #Asc_LF,D0          No, Line Feed ?
  144.           BNE.S    Decode8             No
  145.           MOVEQ    #NewLinCh,D0        Yes, convert it into newline character
  146.           BRA.S     Decode8            Ok, ready for output
  147. Decode7   JSR       (A0)               Call the output function
  148.           TST.B     D1                 Check completion code
  149.           BNE.S     Decode9            If failure return
  150.           ADDQ.L    #1,DChsRecd(A6)    Increment data chars received this trans
  151.           ADDQ.L    #1,TDChRecd(A6)    Increment total data characters received
  152. Decode8   DBF       D3,Decode7         Output char repeat times (at least 1)
  153.           BRA.S     Decode1
  154. Decode9   MOVEM.L   (A7)+,A1/D1-D3     Restore working registers
  155.           RTS
  156.  
  157. ******************************** CmdBfOut *****************************ok
  158. *                                                                     *
  159. *  Output to command buffer, called by Decode.                        *
  160. *                                                                     *
  161. *         Entry conditions : D0.B character to output                 *
  162. *                                                                     *
  163. *         Exit  conditions : D1.B AllOk completion code (0)           *
  164. *                                                                     *
  165. ***********************************************************************
  166. CmdBfOut: MOVE.L    A0,-(A7)           Save register
  167.           LEA       CmdBuf(A6),A0      Point to command buffer start address
  168.           CLR.W     D1                 Clear the index register
  169.           MOVE.B    CmdBfPnt(A6),D1    Load relative pointer to command buffer
  170.           MOVE.B    D0,(A0,D1.W)       Write the character
  171.           ADDQ.B    #1,D1              Increment the index register
  172.           CLR.B     (A0,D1.W)          Make sure buffer is null-terminated
  173.           MOVE.B    D1,CmdBfPnt(A6)    Save the index register
  174.           MOVEQ     #AllOk,D1          Return a positive competion code (0)
  175.           MOVE.L    (A7)+,A0           Restore register
  176.           RTS
  177.  
  178. ********************************* Encode ******************************ok
  179. *                                                                     *
  180. *  Kermit packet encoding procedure, encodes to DataBuf.              *
  181. *                                                                     *
  182. *         Entry conditions : D0.B character to be encoded             *
  183. *                            D2.W current size of output data packet  *
  184. *                                                                     *
  185. *         Exit  conditions : D2.W current size of output data packet  *
  186. *                            D1.L destroyed                           *
  187. *                            D3.B destroyed                           *
  188. *                            A1.L destroyed                           *
  189. *                                                                     *
  190. ***********************************************************************
  191. Encode:   LEA       DataBuf(A6),A1     Pointer to data buffer
  192.           TST.B     ReptFlag(A6)       Repeat processing ?
  193.           BEQ.S     Encode5            No, do prefixing
  194.           CMP.B     Next(A6),D0        Current and next character are equal ?
  195.           BNE.S     Encode4            No
  196.           TST.B     First(A6)          Input in progress
  197.           BNE.S     Encode4            No, first time called
  198.           ADDQ.B    #1,ReptCnt(A6)     Increment the repeat counter
  199.           CMPI.B    #94,ReptCnt(A6)    Below max ?
  200.           BEQ.S     Encode2            No, max reached, must dump
  201.           RTS                          Yes, just count and return
  202.  
  203. Encode1   ADDQ.B    #1,ReptCnt(A6)     More than 2 character to repeat
  204. Encode2   MOVE.B    ReptQuot(A6),(A1,D2.W) Write the repeat quote
  205.           ADDQ.W    #1,D2              Increment the pointer register
  206.           MOVE.B    ReptCnt(A6),D1     Get the repeat count
  207.           ADDI.B    #32,D1             Convert it into a character
  208.           MOVE.B    D1,(A1,D2.W)       Write the repeat count
  209.           ADDQ.W    #1,D2              Increment the pointer register
  210. Encode3   CLR.B     ReptCnt(A6)        Reset the repeat counter
  211.           BRA.S     Encode5            Done repeat processing, do prefixing
  212. Encode4   CMPI.B    #1,ReptCnt(A6)     Run broken, only 2 ?
  213.           BLT.S     Encode5            No, only 1, do it
  214.           BGT.S     Encode1            No, more than 2
  215.           MOVE.B    D0,D3              Yes, do the character twice, save char
  216.           BSR.S     Encode5            Do it the first time
  217.           MOVE.B    D3,D0              Restore the character
  218.           CMP.B     OMPckSiz(A6),D2    Max packet size exceded ?
  219.           BGT.S     Encode3            Yes, do the character again
  220.           MOVE.B    D2,OldSize(A6)     No, update OldSize
  221.           BRA.S     Encode3            Do the character again
  222.  
  223. Encode5   MOVEQ     #$7F,D1            Isolate ASCII part
  224.           AND.B     D0,D1
  225.           BTST      #7,D0              Do 8th bit prefixing if necessary
  226.           BEQ.S     Encode6
  227.           TST.B     Bit8Flag(A6)
  228.           BEQ.S     Encode6
  229.           MOVE.B    Bit8Quot(A6),(A1,D2.W) Write the 8th bit quote
  230.           ADDQ.W    #1,D2              Increment the pointer register
  231.           MOVE.B    D1,D0
  232.  
  233. Encode6   CMPI.B    #' ',D1            Do control prefixing if necessary
  234.           BLT.S     Encode7
  235.           CMPI.B    #Asc_Del,D1        Delete ?
  236.           BNE.S     Encode8            No, character not in control range
  237. Encode7   EORI.B    #64,D0             Uncotrollify
  238.           BRA.S     Encode10
  239.  
  240. Encode8   CMPI.B    #MyCtlQot,D1       Prefix the control prefix
  241.           BEQ.S     Encode10
  242.  
  243.           CMP.B     ReptQuot(A6),D1    If it's the repeat prefix ...
  244.           BNE.S     Encode9
  245.           TST.B     ReptFlag(A6)       ... quote it if doing repeat counts
  246.           BEQ.S     Encode11
  247.           BRA.S     Encode10
  248.  
  249. Encode9   CMP.B     Bit8Quot(A6),D1    Prefix the 8th bit prefix ...
  250.           BNE.S     Encode11
  251.           TST.B     Bit8Flag(A6)       ... if doing 8th-bit prefixes
  252.           BEQ.S     Encode11
  253.  
  254. Encode10  MOVE.B    #MyCtlQot,(A1,D2.W) Write the control quote
  255.           ADDQ.W    #1,D2              Increment the pointer register
  256. Encode11  MOVE.B    D0,(A1,D2.W)       Finally, insert the character
  257.           ADDQ.W    #1,D2              Increment the pointer register
  258.           CLR.B     (A1,D2.W)          Mark the end
  259.           RTS
  260.  
  261. ********************************* SndParm *****************************ok
  262. *                                                                     *
  263. *  Fill the data buffer with my send-init parameters.                 *
  264. *                                                                     *
  265. *         Entry conditions : none                                     *
  266. *                                                                     *
  267. *         Exit  conditions : D0.L data length                         *
  268. *                            D1.L destroyed                           *
  269. *                            A0.L destroyed                           *
  270. *                                                                     *
  271. ***********************************************************************
  272. SndParm:  LEA       DataBuf(A6),A0     Pointer to send buffer
  273.           MOVEQ     #32,D1             Load register for quick addition
  274.  
  275.           MOVE.B    IMPckSiz(A6),D0    Biggest packet I can receive
  276.           ADD.B     D1,D0              Conversion into a printable character
  277.           MOVE.B    D0,(A0)+           Put it into data buffer
  278.  
  279.           MOVE.B    OTimInt(A6),D0     When I want to be timed out
  280.           ADD.B     D1,D0              Conversion into a printable character
  281.           MOVE.B    D0,(A0)+           Put it into data buffer
  282.  
  283.           MOVE.B    IPadNumb(A6),D0    How much padding I need
  284.           ADD.B     D1,D0              Conversion into a printable character
  285.           MOVE.B    D0,(A0)+           Put it into data buffer
  286.  
  287.           MOVE.B    IPadChar(A6),D0    Padding character I want
  288.           EORI.B    #64,D0             Uncontrollify it
  289.           MOVE.B    D0,(A0)+           Put it into data buffer
  290.  
  291.           MOVE.B    IEOL(A6),D0        End-Of-Line character I want
  292.           ADD.B     D1,D0              Conversion into a printable character
  293.           MOVE.B    D0,(A0)+           Put it into data buffer
  294.  
  295.           MOVE.B    OCtlQuot(A6),(A0)+ Control-Quote character I send
  296.  
  297.           MOVE.B    Parity(A6),D0      Parity is enabled or the ...
  298.           OR.B      Bit8Flag(A6),D0    ... 8th bit processing flag is on ?
  299.           BEQ.S     SndParm1           No, no need for 8th bit quoting
  300.           MOVE.B    #My8BQuot,(A0)+    Send my 8th bit quote character
  301.           MOVE.B    Bit8Quot(A6),D0    Get quote
  302.           CMPI.B    #'Y',D0            If other side say YES to do ...
  303.           SEQ       Bit8Flag(A6)       ... 8th bit quoting
  304.           BEQ.S     SndParm2
  305.           BSR       ChkQuot            If other side specify a valid quote ...
  306.           MOVE.B    D0,Bit8Flag(A6)    ... turn the 8th bit quoting flag on
  307.           BRA.S     SndParm2
  308. SndParm1  MOVE.B    #'Y',(A0)+         Normally just say we're willing
  309. SndParm2  MOVE.B    BlChkRq(A6),D0     Block check type
  310.           ADDI.B    #'0',D0            Conversion into a printable character
  311.           MOVE.B    D0,(A0)+           Send it
  312.           MOVE.B    #MyRptQot,(A0)+    Do repeat counts
  313.           CLR.B     (A0)               Terminator
  314.           MOVEQ     #9,D0              Return length
  315.           RTS
  316.  
  317. ******************************** RdParam ******************************ok
  318. *                                                                     *
  319. *  Get the other host's send-init parameters.                         *
  320. *                                                                     *
  321. *         Entry conditions : none                                     *
  322. *                                                                     *
  323. *         Exit  conditions : D0.B destroyed                           *
  324. *                            D1.B destroyed                           *
  325. *                            D2.L destroyed                           *
  326. *                            A0.L destroyed                           *
  327. *                                                                     *
  328. ***********************************************************************
  329. RdParam:  LEA       DataBuf(A6),A0     Pointer to data buffer
  330.           MOVEQ     #32,D2             Load register for quick subtraction
  331.  
  332.           MOVE.B    #DefMxPSz,OMPckSiz(A6) Maximum send packet size
  333.           MOVE.B    #DefTmOut,ITimInt(A6)  When I should time out
  334.           MOVE.B    #DefPadNm,OPadNumb(A6) Number of pads to send
  335.           MOVE.B    #DefPadCr,OPadChar(A6) Padding character to send
  336.           MOVE.B    #DefEOL,OEOL(A6)       EOL character I must send
  337.           MOVE.B    #DefCtlQt,ICtlQuot(A6) Incoming data quote character
  338.           MOVE.B    Bit8Flag(A6),D1        Save 8th bit processing flag
  339.           SF        Bit8Flag(A6)           No 8th bit quoting by default
  340.           MOVE.B    #1,BlChkRq(A6)         Block check type requested
  341.           SF        ReptFlag(A6)           No repeat processing by default
  342.  
  343.           MOVE.B    (A0)+,D0           Maximum send packet size
  344.           BEQ       RdParam9
  345.           SUB.B     D2,D0
  346.           TST.B     SndPSFlg(A6)       Override privilege ?
  347.           BEQ.S     RdParam1           No, continue
  348.           CMPI.B    #10,D0             Yes, less than 10 ?
  349.           BLT.S     RdParam2           Yes, leave unchanged the default value
  350. RdParam1  MOVE.B    D0,OMPckSiz(A6)    No, update
  351.  
  352. RdParam2  MOVE.B    (A0)+,D0           When I should time out
  353.           BEQ       RdParam9
  354.           SUB.B     D2,D0
  355.           TST.B     TimInFlg(A6)       Override privilege ?
  356.           BEQ.S     RdParam3           No, continue
  357.           TST.B     D0                 Yes, less than 0 ?
  358.           BLT.S     RdParam4           Yes, leave unchanged the default value
  359. RdParam3  MOVE.B    D0,ITimInt(A6)     No, update
  360.  
  361. RdParam4  MOVE.B    (A0)+,D0           Number of pads to send
  362.           BEQ       RdParam9
  363.           SUB.B     D2,D0
  364.           MOVE.B    D0,OPadNumb(A6)
  365.  
  366.           MOVE.B    (A0)+,D0           Padding character to send
  367.           BEQ.S     RdParam9
  368.           EORI.B    #64,D0
  369.           MOVE.B    D0,OPadChar(A6)
  370.  
  371.           MOVE.B    (A0)+,D0           EOL character I must send
  372.           BEQ.S     RdParam9
  373.           SUB.B     D2,D0
  374.           CMPI.B    #Asc_STx,D0        Valid range EOL character ?
  375.           BCS.S     RdParam5           No, leave unchanged the default value
  376.           CMPI.B    #Asc_US,D0         Valid range EOL character ?
  377.           BHI.S     RdParam5           No, leave unchanged the default value
  378.           MOVE.B    D0,OEOL(A6)
  379.  
  380. RdParam5  MOVE.B    (A0)+,D0           Incoming data quote character
  381.           BEQ.S     RdParam9
  382.           MOVE.B    D0,ICtlQuot(A6)
  383.  
  384.           MOVE.B    (A0)+,D0           8th bit quote character
  385.           BEQ.S     RdParam9
  386.           MOVE.B    D0,Bit8Quot(A6)
  387.           CMPI.B    #'Y',D0            If flag off, then turn it on ...
  388.           BNE.S     RdParam6           ... if other side has asked us to
  389.           OR.B      Parity(A6),D1      ... or if we need it on
  390.           BEQ.S     RdParam7
  391.           ST        Bit8Flag(A6)
  392.           MOVE.B    #My8BQuot,Bit8Quot(A6)
  393.           BRA.S     RdParam7
  394. RdParam6  BSR       ChkQuot
  395.           MOVE.B    D0,Bit8Flag(A6)
  396.  
  397. RdParam7  MOVE.B    (A0)+,D0           Block check type
  398.           BEQ.S     RdParam9
  399.           SUBI.B    #'0',D0            Range adjust
  400.           CMPI.B    #1,D0              Less than 1 ?
  401.           BCS.S     RdParam8           Yes, invalid
  402.           CMPI.B    #3,D0              Greater than 3 ?
  403.           BHI.S     RdParam8           Yes, invalid
  404.           MOVE.B    D0,BlChkRq(A6)     Ok, store block check type requested
  405.  
  406. RdParam8  MOVE.B    (A0)+,D0           Repeat prefix
  407.           BEQ.S     RdParam9
  408.           MOVE.B    D0,ReptQuot(A6)
  409.           BSR       ChkQuot
  410.           MOVE.B    D0,ReptFlag(A6)
  411. RdParam9  RTS
  412.  
  413. ******************************** Check1 *******************************ok
  414. *                                                                     *
  415. *  Perform a type 1 block check.                                      *
  416. *                                                                     *
  417. *         Entry conditions : A0.L pointer to string buffer            *
  418. *                                                                     *
  419. *         Exit  conditions : D0.B type 1 block check                  *
  420. *                                                                     *
  421. ***********************************************************************
  422. Check1:   MOVE.W    D1,-(A7)           Save working register
  423.           BSR       Check2             Compute numeric sum
  424.           MOVE.W    D0,D1              Compute a type 1 checksum
  425.           ANDI.W    #192,D1
  426.           LSR.W     #6,D1
  427.           ADD.W     D1,D0
  428.           ANDI.W    #63,D0
  429.           MOVE.W    (A7)+,D1           Restore working register
  430.           RTS
  431.  
  432. ******************************** Check2 *******************************ok
  433. *                                                                     *
  434. *  Perform a type 2 block check.                                      *
  435. *                                                                     *
  436. *         Entry conditions : A0.L pointer to string buffer            *
  437. *                                                                     *
  438. *         Exit  conditions : D0.W type 2 block check (numeric sum).   *
  439. *                                                                     *
  440. ***********************************************************************
  441. Check2:   MOVE.W    D1,-(A7)           Save working register
  442.           CLR.W     D1                 Clear the sum register
  443.           CLR.W     D0
  444. Check21   MOVE.B    (A0)+,D0           Get a character
  445.           BEQ.S     Check22            Exit if EOL
  446.           BSR       HndlPar            Handle parity
  447.           ADD.W     D0,D1              Sum
  448.           BRA.S     Check21            Repeat until EOL
  449. Check22   MOVE.W    D1,D0              Return numeric sum
  450.           MOVE.W    (A7)+,D1           Restore working register
  451.           RTS
  452.  
  453. ******************************** Check3 *******************************ok
  454. *                                                                     *
  455. *  Perform a type 3 block check, calculates the 16-bit CRC using a    *
  456. *  byte oriented tableless algorithm invented by Andy Lowry from      *
  457. *  Columbia University. The magic number $1081 is derived from the    *
  458. *  CRC-CCITT polynomial x^16+x^12+x^5+1.                              *
  459. *                                                                     *
  460. *         Entry conditions : A0.L pointer to string buffer            *
  461. *                                                                     *
  462. *         Exit  conditions : D0.L type 3 block check (CRC-CCITT).     *
  463. *                                                                     *
  464. ***********************************************************************
  465. Check3:   MOVEM.L   D1-D3,-(A7)        Save working registers
  466.           CLR.L     D1                 Clear character register
  467.           CLR.L     D2                 Clear CRC register
  468. Check31   MOVE.B    (A0)+,D0           Get a character
  469.           BEQ.S     Check32            Null, end of string buffer
  470.           BSR       HndlPar            Remove parity bit if necessary
  471.           MOVE.B    D0,D1              Load the character register
  472.           MOVE.L    D1,D3              Low order nibble
  473.           EOR.L     D2,D3
  474.           MOVEQ     #$0F,D0
  475.           AND.L     D0,D3
  476.           ASR.L     #4,D2
  477.           MULU      #$1081,D3
  478.           EOR.L     D3,D2
  479.           MOVE.L    D1,D3              High order nibble
  480.           LSR.L     #4,D3
  481.           EOR.L     D2,D3
  482.           MOVEQ     #$0F,D0
  483.           AND.L     D0,D3
  484.           ASR.L     #4,D2
  485.           MULU      #$1081,D3
  486.           EOR.L     D3,D2
  487.           BRA.S     Check31            Repeat until end of string buffer
  488. Check32   MOVE.L    D2,D0              Return CRC-CCITT
  489.           MOVEM.L   (A7)+,D1-D3        Restore working registers
  490.           RTS
  491.  
  492. ******************************** BumpPckN *****************************ok
  493. *                                                                     *
  494. *  Bump packet counters.                                              *
  495. *                                                                     *
  496. *         Entry conditions : none                                     *
  497. *                                                                     *
  498. *         Exit  conditions : none                                     *
  499. *                                                                     *
  500. ***********************************************************************
  501. BumpPckN: MOVE.B    PackNum(A6),PrevPckN(A6) Save previous packet number
  502.           MOVE.B    NextPckN(A6),PackNum(A6) Update current packet number
  503.           ADDQ.B    #1,NextPckN(A6)    Increment next packet number
  504.           ANDI.B    #63,NextPckN(A6)   Modulo 64
  505.           RTS
  506.  
  507. *********************************** CpStrLn ***************************ok
  508. *                                                                     *
  509. *  Copy a null terminated string to a buffer adding a leading         *
  510. *  encoded character count.                                           *
  511. *                                                                     *
  512. *         Entry conditions : A0.L source string buffer address        *
  513. *                            A1.L target buffer address               *
  514. *                                                                     *
  515. *         Exit  conditions : A1.L target buffer next char address     *
  516. *                            D0.L destroyed                           *
  517. *                            D1.B destroyed                           *
  518. *                                                                     *
  519. ***********************************************************************
  520. CpStrLn:  MOVEQ     #0,D0              Preset the counter/index register
  521. CpStrLn1  MOVE.B    (A0)+,1(A1,D0.W)   Move a character
  522.           BEQ.S     CpStrLn2           Exit on end of string
  523.           ADDQ.W    #1,D0              Increment the counter/index register
  524.           BRA.S     CpStrLn1           Loop for all characters
  525. CpStrLn2  MOVE.B    D0,D1              Get the length
  526.           BEQ.S     CpStrLn3           Return if source was null
  527.           ADDI.B    #32,D1             Encode length
  528.           MOVE.B    D1,(A1)            Write it on the first target buffer byte
  529.           LEA       1(A1,D0.W),A1      Address of next available buffer byte
  530. CpStrLn3  RTS
  531.  
  532. ******************************** ChkQuot ******************************ok
  533. *                                                                     *
  534. *  Check if a character is a valid quote.                             *
  535. *                                                                     *
  536. *         Entry conditions : D0.B character to check                  *
  537. *                                                                     *
  538. *         Exit  conditions : D0.B completion code                     *
  539. *                                                                     *
  540. ***********************************************************************
  541. ChkQuot   CMPI.B    #'!',D0
  542.           BCS.S     ChkQuot2
  543.           CMPI.B    #'>',D0
  544.           BLS.S     ChkQuot1
  545.           CMPI.B    #'`',D0
  546.           BCS.S     ChkQuot2
  547.           CMPI.B    #$7E,D0
  548. ChkQuot1  SLS       D0
  549.           RTS
  550. ChkQuot2  SF        D0
  551.           RTS
  552.  
  553.           ends
  554.           END
  555.