;****************************************************************************
;* Copyright 1996 MBARI							    *
;****************************************************************************
;* $Header  : argoss.s,v 3.2 95/04/11 14:03:38 hebo Exp $		    *
;* Summary  : Assembly language routines for Argos driver		    */
;* Filename : argoss.s							    *
;* Author   : Robert Herlien						    *
;* Project  : OASIS Mooring Controller                                      *
;* $Revision: 4.4 $							    *
;* Created  : 09/25/96                                                      *
;*									    *
;* 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-12 checksum on each ARGOS buffer, then	    *
; inserts the buffer ID and checksum in the first word of the buffer	    *
; The checksum is calculated using the standard CRC-12 check polynomial	    *
; of x^12 + x^11 + x^3 + x^2 + x + 1.  The data stream that it is calculated*
; over is the words 1-15 of the data FOLLOWED by word 0 of the data.  This  *
; is done in order to put the ID and checksum in the first word.	    *
;****************************************************************************

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

ARGOS_WORDS	equ	16
ARGOS_SIZE	equ	(2 * ARGOS_WORDS)

CRC12		equ	180fh
CRC_MSB		equ	12


;*****************************************************************************
;  Scratch Register for calcArgosChksums
;
		RSEG

argosBufNum:	dsw	1


		CSEG

PUBLIC	calcArgosChksums


;*****************************************************************************
; crcOneWord - Accumulate CRC-12 checksum for one data word
;	       Subroutine for calcArgosChksums
;
; The register usage during this routine is as follows:
;
; Inputs:   tmp0 = work to chksum
;	    tmp2 = current CRC-12 checksum
;	    Must save tmp4b, tmp6
;	    Can use tmp5b
;
; Output:   tmp2 = new CRC-12 checksum
;

crcOneWord:
	ldb	tmp5b, #16		;16 bits in a word
crcOneBit:
	shll	tmp0, #1		;Shift MSBit of data into chksum
	bbc	tmp2, CRC_MSB, noCrcMsb	;See if MSB of 12 bit chksum is set
	xor	tmp2, #CRC12		;If so, XOR with CRC polynomial
noCrcMsb:
	djnz	tmp5b, crcOneBit	;Repeat for bits in word
	ret


;*****************************************************************************
; calcArgosChksums - Calculate checksum on buffer
;
; Void	calcArgosChksums( ArgosUnion *dp, Nat16 numBufs );
;
; The register usage during this routine is as follows:
; tmp0 - current data word
; tmp2 - checksum
; tmp4 - counters
; tmp6 - data ptr

calcArgosChksums:
	ld	tmp6, 2[SP]		;Point to set of 7 data buffers
	ld	argosBufNum, R0

calcOneChksum:
	ld	tmp2, R0		;Init checksum to 0
	st	R0, [tmp6]+		;Skip ID word for now, set to 0
	ldb	tmp4b, #ARGOS_WORDS - 1 ;Calc chksum of 15 data words first
calcOneWord:
	ld	tmp0, [tmp6]+		;Get next word
	scall	crcOneWord		;Compute checksum on it
	djnz	tmp4b, calcOneWord	;Repeat for words in message

	ld	tmp0, argosBufNum	;Store buffer number in upper nibble
	shl	tmp0, #12		; of ID word, zero LSB 12 bits
	scall	crcOneWord		;Compute checksum on ID + zeros
	ld	tmp0, tmp2		;Move CRC to tmp0
	shl	tmp0, #4		;Shift overall CRC to MSB 12 bits
	ld	tmp2, argosBufNum	;Get buffer ID again
	shll	tmp0, #12		;Shift buf ID to MSB 4 bits of tmp2,
					;   CRC to LSB 12 bits of tmp2
	st	tmp2, -ARGOS_SIZE[tmp6] ;Store ID/CRC in first word of buffer

	inc	argosBufNum		;Go to next buffer
	cmp	argosBufNum, 4[SP]
	blt	calcOneChksum
	ret

	END
