;Entry_CRC
;-----------
;Set ADFFS$CRC to the calculated CRC of a range of memory 

;Entry:
; R0 - commandline
; R1 - number of parameters

.Entry_ADFCRC
 STMFD   R13!, {R1-R6, R14}
 LDR     R12, [R12, #0]

 TEQ     R1, #0				;print the last CRC?
 BEQ     _print
 CMP     R1, #2
 BLO     _generic_error			;need at least two parameters

 MOV     R5, R1				;R5=parameter count

 MOV     R1, R0				;command tail
 MOV     R0, #16			;base 16 number
 SWI     XOS_ReadUnsigned		;read the value PRM1-460
 MOVVC   R3, R2				;R3=start
 SWIVC   XOS_ReadUnsigned		;read the value PRM1-460
 LDMVSFD R13!, {R1-R6, PC}
 MOV     R6, R1				;R6=next parameter

 MOV     R0, R3				;R0=start
 SUBS    R1, R2, R3			;R1=length
 LDMLEFD R13!, {R1-R6, PC}		;exit if length<=0
 BL      crc32
 STR     R2, [R13, #-4]!

 MOV     R1, R13
 MOV     R2, #4
 MOV     R3, #0
 MOV     R4, #1				;its a number
 ADR     R0, Set_CRC
 SWI     XOS_SetVarVal			;PRM1-316
 LDR     R3, [R13], #4			;R3=CRC

 CMP     R5, #3				;do we need to check the CRC?
 LDMLOFD R13!, {R1-R6, PC}		;NO

 MOV     R0, #16			;base 16 number
 MOV     R1, R6				;next parameter
 SWI     XOS_ReadUnsigned		;read the value PRM1-460
 LDMVSFD R13!, {R1-R6, PC}
 MOV     R6, R1				;R6=next parameter

 TEQ     R2, R3				;does the CRC match
 LDMEQFD R13!, {R1-R6, PC}		;YES, exit

 CMP     R5, #4				;is there an filename?
 BLO     _generic_error			;NO

 LDR     R0, [R12, #crc32_table - VARS]	;R0=error buffer
 ADD     R0, R0, #1024			;offset to error space
 MOV     R1, R6				;R1=filename
 BL      skip_spaces_R1
 BCC     _generic_error			;exit, if end of commandline

 ADR     R4, Error_CRCFail
 LDR     R5, [R4], #4
 STR     R5, [R0, #0]
 ADD     R6, R0, #4			;R6 is 252 bytes for error string
 MOV     R3, #251
 ._L1					;copy the filename
   STRB    R2, [R6], #1
   LDRB    R2, [R1], #1
   CMP     R2, #32
   MOVEQ   R4, #0			;ignore our "file doesn't match"
   SUBHSS  R3, R3, #1
 BHS     _L1				;will terminate if R3=0 or R2<32

 TEQ     R3, #0				;did we hit the limit
 TEQNE   R4, #0				;are we going to ignore our string
 BEQ     _skip_our_message
 
 ._L2					;copy our error string
   LDRB    R5, [R4], #1
   STRB    R5, [R6], #1
   TEQ     R5, #0
   SUBNES  R3, R3, #1
 BNE     _L2

 ._skip_our_message
 MOV     R5, #0
 STRB    R5, [R6]
B       _exit_error

._generic_error
 ADR     R0, Error_CRCFail_generic

._exit_error
 MOV     R1, #1 << 31
 ADDS    R1, R1, R1			;set V
LDMFD   R13!, {R1-R6, PC}


._print
 SUB     R13, R13, #8
 ADR     R0, Set_CRC			;read ADFFS$CRC
 MOV     R1, R13			;used this as a tmp buffer
 MOV     R2, #8
 MOV     R3, #0
 MOV     R4, #0
 STR     R3, [R13]
 SWI     XOS_ReadVarVal			;PRM1-314
 LDR     R1, [R13], #8
 BL      outputHexTruncated
 SWI     XOS_NewLine
LDMFD   R13!, {R1-R6, PC}


;crc32
;-----
;calculate a ZIP compatible CRC32

;Entry:
; R0=start
; R1=length
; R2=starting CRC
;
;Exit:
; R0,R1 - corrupt
; R2=CRC

.crc32
 STMFD   R13!, {R4-R5, R14}

 LDR     R5, [R12, #crc32_table - VARS]
 MVN     R2, #0				;start CRC with FFFFFFFF
 ._L1
   LDRB    R4, [R0], #1			;get next byte
   EOR     R4, R4, R2
   AND     R4, R4, #&FF
   LDR     R14, [R5, R4, LSL #2]
   EOR     R2, R14, R2, LSR #8
   SUBS    R1 ,R1, #1
 BNE       _L1
LDMFD   R13!, {R4-R5, PC}




;init_crc32
;----------

;Entry:
; R12=pointer to VARS

.init_crc32
 STMFD   R13!, {R1-R4, R14}

 MOV     R0, #Module_Claim
 MOV     R3, #1024 + 256		;1KB for CRC table / 256 for error
 SWI     XOS_Module
 LDMVSFD R13!, {R1-R4, PC}
 STR     R2, [R12, #crc32_table - VARS]

 LDR     R4, _crc32
 MOV     R1, #255
 ._L3
   MOV     R0, R1
   MOV     R3, #8
   ._L4
     MOVS    R0, R0, LSR #1
     EORCS   R0, R0, R4
     SUBS    R3, R3, #1
   BNE     _L4

   STR     R0, [R2, R1, LSL #2]
   SUBS    R1, R1, #1
 BPL     _L3

 SUBS    R0, R0, R0			;clear V
LDMFD   R13!, {R1-R4, PC}

._crc32	DCD &EDB88320
