The checksum on a zone is calculated/checked as below

;entry
; R0 -> start
; R1 zone length

;exit
; LR check byte, Z=0 <=> good

NewCheck ROUT
 Push   "R1,R2,LR"
 MOV    LR, #0
 ADDS   R1, R1, R0              ;C=0
loop
 LDR    R2, [R1, #-4] !
 ADCS   LR, LR, R2
 TEQS   R1, R0          ;preserves C
 BNE    loop
 AND    R2, R2, #&FF    ;ignore old sum
 SUB    LR, LR, R2
 EOR    LR, LR, LR, LSR #16
 EOR    LR, LR, LR, LSR #8
 AND    LR, LR, #&FF
 CMPS   R2, LR
 Pull   "R1,R2,PC"

****************************************************************************


The checksum on a directory is calculated/checked as below


; Directory Start
                ^ 0
StartMasSeq     # 1
StartName       # 4
DirFirstEntry   # 0

; Old Directory End
                ^ 0
                # -1
DirCheckByte    # 0     ;RETRO DEFINITION was reserved

                # -4
EndName         # 0

                # -1
EndMasSeq       # 0

                # -14   ;reserved

DirTitleSz      * 19
                # -DirTitleSz
OldDirTitle     # 0

                # -3
OldDirParent    # 0

                # -NameLen
OldDirName      # 0

                # -1
OldDirLastMark  # 0     ;dummy last entry marker

; New Directory End
                ^ 0
                # -1
        ASSERT  DirCheckByte=@

                # -4
        ASSERT  EndName=@

                # -1
        ASSERT  EndMasSeq=@

                # -NameLen
NewDirName      # 0

                # -DirTitleSz
NewDirTitle     # 0

                # -3
NewDirParent    # 0

                # -1    ;reserved
                # -1    ;reserved

                # -1
NewDirLastMark  # 0     ;dummy last entry marker



; ================
; TestDirCheckByte
; ================

; entry
;  R3 ind disc add of dir
;  R5 -> dir start
;  R6 -> dir end

; exit
;  LR check byte
;  Z  clear if matches existing byte

TestDirCheckByte
 Push   "R0-R2,R5,R7,LR"
 BL     EndDirEntries                   ;(R3,R5,R6->R0)
 BL     TestDir                         ;(R3->LR,Z)
 ADDEQ  R7, R6, #NewDirLastMark+1       ;dir tail
 ADDNE  R7, R6, #OldDirLastMark+1
05
 BIC    R1, R0, #3
 MOV    R2, #0
10                              ;whole words before end of entries
 LDR    LR, [R5],#4
 EOR    R2, LR, R2,ROR #13
 TEQS   R5, R1
 BNE    %BT10
20                              ;odd bytes before end of entries
 LDRNEB LR, [R5], #1            ;not first pass through loop
 EORNE  R2, LR, R2,ROR #13
 TEQS   R5, R0
 BNE    %BT20

 MOV    R5, R7
30                              ;odd bytes before at start of tail
 TSTS   R5, #3
 LDRNEB LR, [R5],#1
 EORNE  R2, LR, R2, ROR #13
 BNE    %BT30

 ASSERT DirCheckByte=-1         ;dont include last word as it contains
 SUB    R1, R6, #4              ;the check byte
40                              ;whole words in tail
 LDR    LR, [R5],#4
 EOR    R2, LR, R2,ROR #13
 TEQS   R5, R1
 BNE    %BT40

 EOR    R2, R2, R2, LSR #16     ;reduce to 8 bits
 EOR    R2, R2, R2, LSR #8
 AND    R2, R2, #&FF

 LDRB   LR, [R6,#DirCheckByte]  ;compare with old check byte
 TEQS   R2, LR
 MOV    LR, R2

 Pull   "R0-R2,R5,R7,PC"


; =============
; EndDirEntries
; =============

; Find the end of the list of entries in a dir

; entry
;  R3 ind disc add of dir
;  R5 -> dir start
;  R6 -> dir end

; exit
;  R0 -> first empty entry

EndDirEntries ROUT
 Push   "R2,LR"
 BL     TestDir                 ;(R3->LR,Z)
 ADDEQ  R2, R6, #NewDirLastMark
 ADDNE  R2, R6, #OldDirLastMark
 ADD    R0, R5, #DirFirstEntry
 SUB    R0, R0, #DirEntrySz
10                              ;loop examining entries
 LDRB   LR, [R0,#DirEntrySz] !
 CMPS   LR, #0                  ;until null entry
 CMPNES R0, R2                  ;or exhausted
 BLO    %BT10
 MOVHI  R0, R2
 Pull   "R2,PC",,^
