;****************************************************************************
;* Copyright 1998 MBARI							    *
;****************************************************************************
;* $Header  : ymodems.s,v 3.2 95/04/11 14:03:38 hebo Exp $		    *
;* Summary  : Assembly language routines for YModem protocol		    *
;* Filename : ymodems.s							    *
;* Author   : Robert Herlien (rah)					    *
;* Project  : OASIS Mooring Controller                                      *
;* $Revision: 4.4 $							    *
;* Created  : 08/20/98                                                      *
;*									    *
;* MBARI provides this documentation and code "as is", with no warranty,    *
;* express or implied, of its quality or consistency. It is provided without*
;* support and without obligation on the part of the Monterey Bay Aquarium  *
;* Research Institute to assist in its use, correction, modification, or    *
;* enhancement. This information should not be published or distributed to  *
;* third parties without specific written permission from MBARI.            *
;*									    *
;****************************************************************************
; This module calculates a CRC-16 checksum on a YModem buffer using the	    *
; standard CRC-16 polynomial x^16 + x^12 + x^5 + 1.			    *
;****************************************************************************

;
YMODEMS		MODULE
;
$INCLUDE(..\C196\INCLUDE\8096.INC)
$INCLUDE(OASIS.INC)
;

CRC16		equ	1021h


		CSEG

PUBLIC	calcYmodemCRC
PUBLIC	calcYmodemChksum


;*****************************************************************************
; ymCrcOneWord - Accumulate CRC-16 checksum for one data Word
;	         Subroutine for calcYmodemChksum
;
; The register usage during this routine is as follows:
;
; Inputs:   tmp0 = byte to chksum
;	    tmp2 = current CRC-16 checksum
;	    Must save tmp4, tmp6
;
; Output:   tmp2 = new CRC-16 checksum
;

ymCrcOneWord:
	push	tmp4
	ldb	tmp5b, #16		;16 bits in a word
ymCrcOneBit:
	shll	tmp0, #1		;Shift MSBit of data into chksum
	bnc	noYMCrcMsb		;See if MSB of 16 bit chksum is set
	xor	tmp2, #CRC16		;If so, XOR with CRC polynomial
noYMCrcMsb:
	djnz	tmp5b, ymCrcOneBit	;Repeat for bits in word
	pop	tmp4
	ret


;*****************************************************************************
; calcYModemCRC - Calculate CRC-16 checksum on buffer
;
; Nat16	calcYModemChksum( char *p, Nat16 len );
;
; The register usage during this routine is as follows:
; tmp0 - current data word
; tmp2 - checksum
; tmp4 - loop counters
; tmp6 - data ptr

calcYModemCRC:
	ld	tmp6, 2[SP]		;Point to data
	ld	tmp4, 4[SP]		;Get data cntr
	shr	tmp4, #1		;change cntr to words
	ld	tmp2, R0		;clear init CRC

crcYMOneWord:
	ldb	tmp1b, [tmp6]+		;Get next word but byte-swap
	ldb	tmp0b, [tmp6]+
	scall	ymCrcOneWord
	djnzw	tmp4, crcYMOneWord	;Repeat for words in message

	ld	tmp0, R0
	scall	ymCrcOneWord		;Shift in a word of zeroes

	ld	tmp0, tmp2		;Return chksum in tmp0
	ret


;*****************************************************************************
; calcYModemChksum - Calculate simple checksum on buffer
;		     
; Nat16	calcYModemChksum( char *p, Nat16 len );
;
; The register usage during this routine is as follows:
; tmp0 - checksum
; tmp4 - loop counter
; tmp6 - data ptr

calcYModemChksum:
	ld	tmp6, 2[SP]		;Point to data
	ld	tmp4, 4[SP]		;Get data cntr
	ld	tmp0, R0

chksumYMOneByte:
	addb	tmp0b, [tmp6]+
	djnzw	tmp4, chksumYMOneByte	;Repeat for bytes in message
	ldb	tmp1b, R0

	END
