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.
Clobbers: AF, BC, DE, HLPreserves: IX, SP
Progress flag stored at $A100 (0 = no progress, 1 = progress made during pass).
; ------------------------------------------------------------
; 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