CRECKSUM
.Page
;++
;
; CreCksum -- Create checksum using 524 byte i/o buffer
;
; Algorithm:
; A sector is composed of 524 user adata bytes and a 3 byte
; checksum. These are translated into 6 bit nibbles which are used to
; Look up GCR codewords to be written to the disk. The data is encode
; as follows: CSUMA, CSUMB, & CSUMC are "registers" used fo accumulating
; the checksum. ByteA, ByteB, & ByteC contain 3 bytes from the data buffer
;
; 1. Rotate CSUMC left
; CSUMC[65432107] <- CSUMC[76543210]
; Carry <- CSUM[7]
; 2. CSUMA <- CSUMA + ByteA + Carry from step 1
; 3. ByteA <- ByteA Xor CSUMC
; 4. CSUMC <- CSUMC + ByteB + Carry from step 2
; 5. ByteB <- ByteB Xor CSUMA
; 6. CSUMB <- CSUMB + ByteC + carry from Step 3
; 7. ByteC <- ByteC Xor CSUC
;
; Propagation of carry among three checksum bytes:
;
; ------------------------
; v v Note: Carry out of CsumC is from rotate
; ^--CSUMC <-- CSUMB <-- CSUMA <--
;
; REGISTERS
; IN
; All = Any valye
; OUT
; All = Destroyed
;
;--
.Page
CreCksum .Equ * ; Entry point for all callers
Lda #00
Sta Cksum1
Sta Cksum2 ; Zero only two bytes
Sta InxptrL ; Init pointer for 5 cycle index fetch
Sta InxptrH
Inc InxPtrH ; Start on page 1
Ldy #0F4 ; Last twelve bytes in page 1
CrTop .Equ * ; Initially 'A' = 0
Asl A ; Move high bit to carry
Php ; Save status bits on stack
Adc #00 ; Move carry bit to low bit (8 bit rotate)
Sta Cksum3
Plp ; Restore Status bits
Lda @InxPtrL,y ; First of three bytes in loop
Tax
Eor Cksum3 ; combine checksum w/ data
Sta @InxPtrL,y ; Data ==> buffer
Txa
Adc CkSum1 ; Add with above carry
Sta Cksum1
Iny
Bne $20 ; end of page two data
Inc InxPtr ; point to page three
$20 Lda @InxPtrL,y ; Second of three bytes
Tax
Adc Cksum2 ; Add to second checksum byte
Sta Cksum2
Txa
Eor Cksum1 ; Combine checksum / data
Sta @InxPtrL ; Data ==> buffer
Iny
Beq $60 ; End of page three data
Lda @InxPtrL,y ; Third of three bytes
Tax ; Save data value
Eor Cksum2 ; Combine checksum w/ data value
Sta @InxPtrL,y ; Data ==> buffer
Txa ; Restore data value
Adc Cksum3 ; Add to third checksunm byte leave in A
Iny
Bne CrTop ; Not at page boundary, loop
Inc InxPtrH ; start w/ page 2 data
Bne CrTop ; branch always taken
$60 Rts ; End of creating a checksum