The Need for Data Integrity

When data is transferred over an unreliable medium (like a cassette tape or a network connection), or when code is loaded from disk, electrical noise or corruption can change the data bytes. A Checksum or CRC provides a simple way to verify that the data received is exactly what was sent.

Method 1: The Simple Checksum (The Fast Way)

A simple checksum is the fastest method. It involves adding up every byte in the data block.

The Principle: Sum every byte, and discard any overflow (carry). The final 8-bit sum is the checksum.

The Z80 Routine (Simplified):

CHECKSUM_ROUTINE:
    LD   HL, START_ADDRESS  ; HL ← Address of the data block
    LD   BC, BLOCK_LENGTH   ; BC ← Length of the block
    LD   A, 0               ; A ← The 8-bit accumulator (checksum result)

CHECK_LOOP:
    ADD  A, (HL)            ; Add current byte ← A + (HL). Carry is discarded.
    INC  HL                 ; Move to the next byte
    DEC  BC                 ; Decrement counter
    LD   D, B               ; Check if BC is zero (16-bit check)
    OR   C                  ; (D OR C) is zero only if BC=0
    JP   NZ, CHECK_LOOP     ; Loop if BC is Not Zero
    
    ; The 8-bit checksum is now in the Accumulator (A).
    RET

Method 2: Cyclic Redundancy Check (CRC)

The CRC is a much more robust error-checking method (used in networks and modern file systems) because it is based on polynomial long division, making it better at detecting bursts of errors.

The Challenge: CRC calculation is highly complex and requires many iterations of shifts, XORs, and conditional logic. It is typically too slow for real-time processing on the Z80 unless the data blocks are very small.

The Algorithm Focus: The code implements the polynomial division using the Z80’s XOR′ and **shifting** instructions (SLA′, `RRCA′). The algorithm iteratively calculates the remainder of the division. The final remainder is the CRC value.

Verifying the Data

To verify data integrity, the receiving system:

  1. Calculates the checksum/CRC of the received data.
  2. Compares the calculated value to the original checksum/CRC byte appended to the data packet.

The Final Check:

    CALL CHECKSUM_ROUTINE  ; A ← calculated checksum
    CP   (CHECKSUM_ADDR)   ; Compare calculated A with stored checksum
    JP   Z, DATA_GOOD      ; Jump if Zero flag is set (match!)
    
    CALL DATA_CORRUPTED    ; Error handler