home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
BBS_UTIL
/
BM0406_A.ZIP
/
BMASM.ZIP
/
XMODEM.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-02-06
|
5KB
|
125 lines
; 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.
; Modified 02/06/93 by Richie Molinelli
; Modified for use with BASIC v7.x /Fs (far string) compile option.
; Original mod for far strings done by Scott McNay. Scott eliminated
; the 1K buffer for the string. I reinstituted the buffer and retained
; the original code and logic for reference. Many thanks to Scott McNay
; for the original breakthrough in adapting the .ASM routine for far string
; compatibility.
EXTRN StringAddress:FAR ;FS020601
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
;
;FS020601 MOV SI,[BP+14] ;GET STRING DESCRIPTOR
;FS020601 MOV BL,[SI+ 2] ;REARRANGE LOW/HIGH BYTES
;FS020601 MOV BH,[SI+ 3] ;NOW BX HOLDS THE ADDRESS OF THE STRING
;FS020601 MOV STRG_LOC,BX ;STORE IT
;FS020601 MOV AX,[SI] ;GET STRING LENGTH
;FS020601 MOV STRG_LEN,AX ;STORE IT
;
PUSH [BP+14] ;FS020601
CALL StringAddress ;FS020601
MOV STRG_LOC,AX ;FS020601 Save string address
MOV STRG_LEN,CX ;FS020601 Save string length
PUSH DS ;FS020601 Save DS
PUSH DX ;FS020601
POP DS ;FS020601 Set segment address
MOV CX,CS:STRG_LEN ;STORE LENGTH IN CX
MOV SI,CS: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
;
;FS020601 PUSH DS ;SAVE DS
PUSH CS
POP DS
MOV CX,CS: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