;
; crc32.s
;
; 32-bit CRC calculation
;
;  1993-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; This file is part of Straylight's Dynamic Linking System (SDLS)
;
; SDLS is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; SDLS is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with SDLS.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		AREA	|C$$Code|,CODE,READONLY

;----- crc32 ----------------------------------------------------------------
;
; Calculates 32-bit Cyclic Redundancy Check values for a given chunk of
; data.  A calculation may be performed in stages.
;
; The method used is the PKZip/Ethernet algorithm.  For reference, the
; parameters to the Rocksoft^tm Model CRC Algorithm are:
;
; Name   : Straylight Cyclic Redundancy Check algorithm
; Width  : 32
; Poly   : 04C11DB7
; Init   : FFFFFFFF
; RefIn  : True
; RefOut : True
; XorOut : FFFFFFFF
; Check  : CBF43926
;
; The routine is very small (and hopefully pretty quick, too).  The table
; is rather large, though.
;
; The code can be called from any APCS-conformant langauge.  The C prototype
; is
;
; 	long crc32(	long seed,	/* R0==seed value (0 to start)	*/
;			void *data,	/* R1==pointer to data to check	*/
;			size_t size,	/* R2==length of data		*/
;			int diff);	/* R3==diff between check bytes */
;
; In normal use, the seed is 0 for the first call, and the previoud returned
; value for subsequent calculations.
;
; The 'diff' value gives the difference in address between bytes to check,
; so diff==1 means check all bytes, diff==2 means check every other byte,
; and so on.
;

		EXPORT	crc32
crc32		ROUT

		STMFD	R13!,{R1-R4,R14}
		MVN	R0,R0			;R0 = R0 XOR &FFFFFFFF!
		ADR	R4,crctable		;Point to my magic table

00		LDRB	R14,[R1],R3		;Get byte from stream
		EOR	R14,R14,R0		;XOR register with byte
		AND	R14,R14,#&FF		;Multiply to word, and mask
		LDR	R14,[R4,R14,LSL #2]	;Get word from table
		EOR	R0,R14,R0,LSR #8	;EOR with shifted register
		SUBS	R2,R2,R3		;Decrement counter
		BGT	%b00			;If necessary, branch back
		MVN	R0,R0			;R0 = R0 XOR &FFFFFFFF again
		LDMFD	R13!,{R1-R4,PC}^

		LTORG

;----- The magic table ------------------------------------------------------
;
; The numbers in this table were generated using the Rocksoft^tm Model CRC
; Algorithm Table Generation Table Program V1.0, written by Ross Williams.
; Our thanks to him for placing this program in the public domain.
;

crctable	DCD	&00000000,&77073096,&EE0E612C,&990951BA
		DCD	&076DC419,&706AF48F,&E963A535,&9E6495A3
		DCD	&0EDB8832,&79DCB8A4,&E0D5E91E,&97D2D988
		DCD	&09B64C2B,&7EB17CBD,&E7B82D07,&90BF1D91
		DCD	&1DB71064,&6AB020F2,&F3B97148,&84BE41DE
		DCD	&1ADAD47D,&6DDDE4EB,&F4D4B551,&83D385C7
		DCD	&136C9856,&646BA8C0,&FD62F97A,&8A65C9EC
		DCD	&14015C4F,&63066CD9,&FA0F3D63,&8D080DF5

		DCD	&3B6E20C8,&4C69105E,&D56041E4,&A2677172
		DCD	&3C03E4D1,&4B04D447,&D20D85FD,&A50AB56B
		DCD	&35B5A8FA,&42B2986C,&DBBBC9D6,&ACBCF940
		DCD	&32D86CE3,&45DF5C75,&DCD60DCF,&ABD13D59
		DCD	&26D930AC,&51DE003A,&C8D75180,&BFD06116
		DCD	&21B4F4B5,&56B3C423,&CFBA9599,&B8BDA50F
		DCD	&2802B89E,&5F058808,&C60CD9B2,&B10BE924
		DCD	&2F6F7C87,&58684C11,&C1611DAB,&B6662D3D

		DCD	&76DC4190,&01DB7106,&98D220BC,&EFD5102A
		DCD	&71B18589,&06B6B51F,&9FBFE4A5,&E8B8D433
		DCD	&7807C9A2,&0F00F934,&9609A88E,&E10E9818
		DCD	&7F6A0DBB,&086D3D2D,&91646C97,&E6635C01
		DCD	&6B6B51F4,&1C6C6162,&856530D8,&F262004E
		DCD	&6C0695ED,&1B01A57B,&8208F4C1,&F50FC457
		DCD	&65B0D9C6,&12B7E950,&8BBEB8EA,&FCB9887C
		DCD	&62DD1DDF,&15DA2D49,&8CD37CF3,&FBD44C65

		DCD	&4DB26158,&3AB551CE,&A3BC0074,&D4BB30E2
		DCD	&4ADFA541,&3DD895D7,&A4D1C46D,&D3D6F4FB
		DCD	&4369E96A,&346ED9FC,&AD678846,&DA60B8D0
		DCD	&44042D73,&33031DE5,&AA0A4C5F,&DD0D7CC9
		DCD	&5005713C,&270241AA,&BE0B1010,&C90C2086
		DCD	&5768B525,&206F85B3,&B966D409,&CE61E49F
		DCD	&5EDEF90E,&29D9C998,&B0D09822,&C7D7A8B4
		DCD	&59B33D17,&2EB40D81,&B7BD5C3B,&C0BA6CAD

		DCD	&EDB88320,&9ABFB3B6,&03B6E20C,&74B1D29A
		DCD	&EAD54739,&9DD277AF,&04DB2615,&73DC1683
		DCD	&E3630B12,&94643B84,&0D6D6A3E,&7A6A5AA8
		DCD	&E40ECF0B,&9309FF9D,&0A00AE27,&7D079EB1
		DCD	&F00F9344,&8708A3D2,&1E01F268,&6906C2FE
		DCD	&F762575D,&806567CB,&196C3671,&6E6B06E7
		DCD	&FED41B76,&89D32BE0,&10DA7A5A,&67DD4ACC
		DCD	&F9B9DF6F,&8EBEEFF9,&17B7BE43,&60B08ED5

		DCD	&D6D6A3E8,&A1D1937E,&38D8C2C4,&4FDFF252
		DCD	&D1BB67F1,&A6BC5767,&3FB506DD,&48B2364B
		DCD	&D80D2BDA,&AF0A1B4C,&36034AF6,&41047A60
		DCD	&DF60EFC3,&A867DF55,&316E8EEF,&4669BE79
		DCD	&CB61B38C,&BC66831A,&256FD2A0,&5268E236
		DCD	&CC0C7795,&BB0B4703,&220216B9,&5505262F
		DCD	&C5BA3BBE,&B2BD0B28,&2BB45A92,&5CB36A04
		DCD	&C2D7FFA7,&B5D0CF31,&2CD99E8B,&5BDEAE1D

		DCD	&9B64C2B0,&EC63F226,&756AA39C,&026D930A
		DCD	&9C0906A9,&EB0E363F,&72076785,&05005713
		DCD	&95BF4A82,&E2B87A14,&7BB12BAE,&0CB61B38
		DCD	&92D28E9B,&E5D5BE0D,&7CDCEFB7,&0BDBDF21
		DCD	&86D3D2D4,&F1D4E242,&68DDB3F8,&1FDA836E
		DCD	&81BE16CD,&F6B9265B,&6FB077E1,&18B74777
		DCD	&88085AE6,&FF0F6A70,&66063BCA,&11010B5C
		DCD	&8F659EFF,&F862AE69,&616BFFD3,&166CCF45

		DCD	&A00AE278,&D70DD2EE,&4E048354,&3903B3C2
		DCD	&A7672661,&D06016F7,&4969474D,&3E6E77DB
		DCD	&AED16A4A,&D9D65ADC,&40DF0B66,&37D83BF0
		DCD	&A9BCAE53,&DEBB9EC5,&47B2CF7F,&30B5FFE9
		DCD	&BDBDF21C,&CABAC28A,&53B39330,&24B4A3A6
		DCD	&BAD03605,&CDD70693,&54DE5729,&23D967BF
		DCD	&B3667A2E,&C4614AB8,&5D681B02,&2A6F2B94
		DCD	&B40BBE37,&C30C8EA1,&5A05DF1B,&2D02EF8D

		END
