home *** CD-ROM | disk | FTP | other *** search
- ; Modified 8/24/85 for use with QuickBasic Compiler
-
- ; Heavy modifications 8/31/86 by Jim King
- ; Changed CRC_CALC from the awfulness it was to an algorithm suggested
- ; by Philip Burns. In a test program, this algorithm is over 3 times as
- ; fast as the one previously used by RBBS-PC.
- ; Changed the loop that calculates checksum and calls the CRC to be more
- ; efficient (just about halved the number of instructions).
- ; Note that RBBS-PC.BAS was also modified so that it no longer tacks on
- ; two null bytes to the input string (they were necessary for the old CRC
- ; routine to work correctly).
- ; Once again, thanks to Philip Burns for suggesting the CRC algorithm.
- ; Many thanks also to John Souvestre, who helped me tweak the assembly
- ; routine to run even faster.
-
- XM_CALC SEGMENT PUBLIC 'CODE'
- ASSUME CS:XM_CALC
- PUBLIC XMODEM
- ;
- CHK_SUM DB 0
- STRG_LEN DW 0 ;CHANGED TO LENGTH OF STRING PASSED
- STRG_LOC DW 0
- STRG_MSG DB 1026 DUP (' ') ;COMMAND CHARS (+CR) GO INTO HERE
- ;
- ;
- ;
- XMODEM PROC FAR
- PUSH BP
- MOV BP,SP
- MOV CHK_SUM,0 ;INITIALIZE
- ;
- MOV SI,[BP+14] ;GET STRING DESCRIPTOR
- MOV BL,[SI+ 2] ;REARRANGE LOW/HIGH BYTES
- MOV BH,[SI+ 3] ;NOW BX HOLDS THE ADDRESS OF THE STRING
- MOV STRG_LOC,BX ;STORE IT
- MOV AX,[SI] ;GET STRING LENGTH
- MOV STRG_LEN,AX ;STORE IT
- ;
- MOV CX,STRG_LEN ;STORE LENGTH IN CX
- MOV SI,STRG_LOC ;STORE OFFSET TO STRING IN SI
- PUSH CS
- POP ES
- MOV DI,OFFSET STRG_MSG ;ES:DI = LOCATION OF VARIABLE
- REP MOVSB ;FILL STRG_MSG WITH STRING
- ;
- PUSH DS ;SAVE DS
- PUSH CS
- POP DS
-
- MOV CX,STRG_LEN ;INITIALIZE COUNTER
- MOV SI,OFFSET STRG_MSG ;get address of input string
- XOR DX,DX ;initialize CRC value to 0
- LOOP1:
- LODSB ;get character into AL
- MOV DI,CX ;SAVE CX
- ADD CHK_SUM,AL ;ADD AL TO CHK_SUM
-
- ; this used to be:
- ;CRC_CALC PROC NEAR
- ; this is the CRC calculation routine. It's placed here instead of in
- ; a separate procedure for additional speed.
- ; DX contains the CRC value, AL has the new character. Other registers
- ; are used for temporary storage and scratch work.
- XCHG DH,DL ; CRC := Swap(CRC) XOR Ord(Ch);
- XOR DL,AL
-
- MOV AL,DL ; CRC := CRC XOR ( Lo(CRC) SHR 4 );
- MOV CL,4
- SHR AL,CL
- XOR DL,AL
-
- ; CRC := CRC XOR ( Swap(Lo(CRC)) SHL 4 )
- ; XOR ( Lo(CRC) SHL 5 );
- MOV BL,DL
- MOV AH,DL
- SHL AH,CL
- XOR DH,AH
- XOR BH,BH
- INC CL
- SHL BX,CL
- XOR DX,BX
- ; end of the CRC calculation routine
-
- MOV CX,DI ;RESTORE CX
- LOOP LOOP1 ;do it again
-
-
- POP DS ;RESTORE DS
- MOV BX,DX ;PASS BACK THE CRC VALUE
- MOV SI,[BP+ 6] ;AND CRC HIGH AND LOW BYTES
- MOV [SI],BL
- MOV SI,[BP+ 8]
- MOV [SI],BH
- MOV SI,[BP+10]
- MOV [SI],BX
- MOV BL,CS:CHK_SUM ;PASS BACK THE CHECK SUM
- MOV SI,[BP+12]
- MOV [SI],BL
- ;
- PUSH CS ;CLEAN UP WORK TO RETURN TO BASIC
- POP ES
- POP BP
- RET 10
- XMODEM ENDP
- XM_CALC ENDS
- END