pfm$compute_checksum  ident
.
. This module computes checksums for the permanent file manager.
.
. Registers used in this module are defined as follows:
.
index    equ       8         .index into the data to checksum
                             .This is the offset from the start of the data
p_loc    equ       8         .register pointing to location of data
remaining_bytes    equ  9    .register for number of remaining_bytes of data
result   equ       10        .register for checksum result
data     equ       11        .register for data
amacscr  equ       15        .scratch register for macros
.
index    atrib     #regtyp,#xreg
p_loc    atrib     #regtyp,#areg
remaining_bytes    atrib     #regtyp,#xreg
result   atrib     #regtyp,#xreg
data     atrib     #regtyp,#xreg
amacscr  atrib     #regtyp,#areg
.
         page
. COMMON DECKS
*copy OSA$CYBIL_INTERFACE
         page
*copy OSA$BASIC_REGISTER_EQUATES
         page
.______________________________________________________________
. Name:
.        pfp$compute_checksum
.Purpose:
.        This function computes a checksum for  data.
. Input:
.        loc: Pointer to data to checksum.
.        size: Size in bytes of data to checksum.
. Output:
.        sum: Integer value of checksum for data.
._________________________________________________________
.
.
.        PROCEDURE [XREF] pfp$compute_checksum (loc: ^cell;
.                  size: integer;
.                  VAR sum: integer)
.
.
pfp$compute_checksum     procedur  gated
loc      param     val,pointer
size     param     val,integer
sum      param     ref,integer
.
.
         ploada    p_loc,loc             . get PVA of data to checksum
         ploadx    remaining_bytes,size  . get number of bytes to checksum
         entp      index,0               . index := 0
         entp      result,0              . result := 0
.
looptest brreq     remaining_bytes,x0,done  .IF remaining_bytes = 0 goto DONE
         decr      remaining_bytes,8     . remaining_bytes := remaining_bytes - 8
         brrgt     x0,remaining_bytes,lastbyte .IF remaining_bytes<0 THEN goto lastbyte
         lbyts,8   data,p_loc,index,0    . Load the current word into data
         incr      index,8               . Index := index + 8
         xorx      result,data           . result := exclusive or of result and data
         brreq     x0,x0,looptest        . goto looptest
.
lastbyte entp      x0,7                  . Handle the last bytes
         addr      x0,remaining_bytes    . remaining_bytes := 7 + remaining_bytes
         lbyt,x0   data,p_loc,index,0    . Load the remaining_bytes into data
         xorx      result,data           . result := exclusive or of result and data
done     bss        0                    . All bytes processed
.
         brrne     result,x0,zeroend     . IF result <> 0 goto zeroend
         ente      result,6753(16)       . reset result to arbitrary non-zero number
zeroend  bss        0
         pstorxp   result,sum            . Store result into sum before returning
         return
         page
         align     0,8                   . Allows code to be callable
         use       binding
         address   ce,pfp$compute_checksum
         end                             . pfm$compute_checksum
