Z80 Sudoku — Deterministic Fill Loop (Assembly Implementation)

Implements the deterministic propagation phase described in the solver control structure.

Algorithm: 1. Iterate over all 81 cells. 2. If cell value != 0 (solved), skip. 3. Build candidate mask (9-bit, returned in BC). 4. If mask has exactly one bit set → resolve digit and write to board. 5. Set progress flag. 6. Repeat entire board scan until no progress made.

Register Conventions

Clobbers: AF, BC, DE, HLPreserves: IX, SP

Workspace Usage

Progress flag stored at $A100 (0 = no progress, 1 = progress made during pass).

Assembly Implementation

; ------------------------------------------------------------
; Deterministic_Fill_Loop
; ------------------------------------------------------------
; Repeatedly scans board and fills single-candidate cells
;
; Uses existing routine: Build_Candidate_Mask
;   Input: HL = cell address
;   Output: BC = 9-bit candidate mask
;
; Board base: $A000
; Progress flag: $A100
;
; Clobbers: AF, BC, DE, HL
; Preserves: IX, SP
; ------------------------------------------------------------

Deterministic_Fill_Loop:

DFL_Outer:
    xor a
    ld ($A100), a        ; clear progress flag

    ld hl, $A000         ; HL = board base
    ld b, 81             ; 81 cells to scan

DFL_Cell_Loop:
    ld a, (hl)
    and 0x0F             ; isolate low nibble (cell value)
    jr nz, DFL_Next_Cell ; skip solved cells

    push hl              ; preserve pointer across call
    call Build_Candidate_Mask
    pop hl

    ; BC = candidate mask
    ld a, b
    or c
    jr z, DFL_Next_Cell  ; no candidates (should not happen)

    ; Test if BC is power of two (single candidate)
    ; Method: mask & (mask - 1) == 0

    ld de, 0
    ld d, b
    ld e, c              ; DE = mask

    dec bc               ; BC = mask - 1

    ld a, b
    and d
    ld b, a
    ld a, c
    and e
    ld c, a              ; BC = mask & (mask-1)

    ld a, b
    or c
    jr nz, DFL_Restore   ; not single bit

    ; Single candidate — determine digit index
    ld bc, 1             ; bit counter (digit = 1..9)
    ld de, 1

DFL_Bit_Search:
    ld a, d
    and e
    jr nz, DFL_Write     ; found matching bit

    sla e
    rl d                 ; shift DE left (9-bit)
    inc c                ; increment digit
    jr DFL_Bit_Search

DFL_Write:
    ld a, (hl)
    and 0xF0             ; preserve high nibble
    or c                 ; insert solved digit
    ld (hl), a

    ld a, 1
    ld ($A100), a        ; set progress flag

DFL_Restore:
    ; restore original mask not needed further

DFL_Next_Cell:
    inc hl
    djnz DFL_Cell_Loop

    ld a, ($A100)
    or a
    jr nz, DFL_Outer     ; repeat if progress made

    ret