Z80 Sudoku — Row Validation Routine

Validates that a given row (0–8) contains no duplicate digits 1–9. Assumes board base at $A000. Low nibble (bits 0–3) holds value; 0 = empty. High nibble ignored.

Calling Convention

Input:

• A = row index (0–8)

Output:

• Z flag set if valid (no duplicates)

• Z flag reset if duplicate found

Registers used: A, B, C, D, E, HL

Algorithm

• Compute row base: HL = $A000 + (row * 9)

• Maintain 9-bit seen mask in DE (bits 0–8 used)

• For each of 9 cells:

– Extract low nibble

– Skip if zero

– Test corresponding bit in mask

– If already set → duplicate → return NZ

– Else set bit and continue

; ----------------------------------------
; validate_row
; A = row index (0-8)
; Returns Z if valid, NZ if duplicate
; ----------------------------------------
validate_row:
    push bc
    push de
    push hl

    ; Compute HL = $A000 + row*9
    ld hl, $A000
    ld b, a            ; B = row
    ld c, 9

row_mul_loop:
    or a
    jr z, row_base_ready
    add hl, bc         ; add 9 each iteration
    dec b
    jr row_mul_loop

row_base_ready:
    ld de, 0           ; seen mask = 0
    ld b, 9            ; 9 columns

row_scan_loop:
    ld a, (hl)
    and $0F            ; isolate low nibble
    jr z, row_next     ; skip empty cells

    dec a              ; map 1–9 → 0–8
    ld c, a

    ; Test bit C in DE
    ld a, e
    bit 0, c           ; (placeholder - dynamic test below)

    ; Dynamic bit test
    ld a, 1
    ld b, c
bit_shift_loop:
    or a
    jr z, bit_ready
    sla a
    dec b
    jr bit_shift_loop
bit_ready:

    ld c, a            ; C = bit mask (low byte)
    ld a, e
    and c
    jr nz, row_invalid ; duplicate found

    ; set bit
    ld a, e
    or c
    ld e, a

row_next:
    inc hl
    djnz row_scan_loop

    ; valid row
    xor a              ; set Z flag
    pop hl
    pop de
    pop bc
    ret

row_invalid:
    ld a, 1            ; ensure NZ
    or a
    pop hl
    pop de
    pop bc
    ret