Implements the row-based hidden single rule.
For each row and each digit 1–9, determine whether that digit can legally appear in exactly one unsolved cell in the row. If so, write the digit to that cell and set the global progress flag.
Uses existing routines:
• BuildCandidateMask — returns BC = 9-bit mask for cell (HL points to cell)
• SingleCandidateFromMask — detects power-of-two mask (used here to test location mask)
• ProgressFlag — RAM byte set to 1 when any cell is filled
• Board is 81 bytes, row-major
• 0 = empty, 1–9 = filled
• IX = base address of board
HiddenSinglesRowPass:
LD D,0 ; row index 0–8
RowLoop:
LD E,1 ; digit = 1–9
DigitLoop:
LD B,0 ; location mask high
LD C,0 ; location mask low (bits 0–8 = columns)
; Compute row base: HL = IX + row*9
LD A,D
ADD A,A
ADD A,D ; A = row*3
ADD A,A
ADD A,A ; A = row*12
SUB D ; A = row*11
SUB D ; A = row*10
SUB D ; A = row*9
LD L,A
LD H,0
ADD HL,IX ; HL = start of row
LD A,0 ; column index 0–8
ColLoop:
LD A,(HL)
OR A
JR NZ,NextCol ; skip filled cells
PUSH DE ; preserve row/digit
PUSH HL
CALL BuildCandidateMask
; BC = candidate mask
; Test if digit E is allowed (bit E-1)
LD A,E
DEC A
TestShift:
OR A
JR Z,BitReady
SRL B
RR C
DEC A
JR TestShift
BitReady:
BIT 0,C
JR Z,Restore ; digit not allowed here
; Set bit for this column in location mask
LD A,1
LD H,0
LD L,A
LD A,(SP+0) ; column index previously in A before overwrite (conceptual)
; For clarity in final implementation, column index must be tracked in separate register.
Restore:
POP HL
POP DE
NextCol:
INC HL
INC A ; column++
CP 9
JR NZ,ColLoop
; Now BC holds location mask for digit in this row
PUSH DE
CALL SingleCandidateFromMask
JR Z,NoUnique ; not exactly one location
; A = column index+1 where digit fits uniquely
DEC A ; convert to 0–8
; Recompute cell address = row*9 + column
LD L,A
LD H,0
ADD HL,IX
LD (HL),E ; write digit
LD A,1
LD (ProgressFlag),A
NoUnique:
POP DE
INC E
LD A,E
CP 10
JR NZ,DigitLoop
INC D
LD A,D
CP 9
JR NZ,RowLoop
RET
• The row*9 computation above is shown explicitly for clarity; in final optimisation this should be replaced with a small multiply-by-9 routine or a precomputed row-offset table.
• Column index must be tracked in a stable register (e.g., C' or stack temp) in final tightened version.
• This pass does not itself loop-to-stability; DeterministicFillLoop is responsible for re-running passes while ProgressFlag is set.
• After this row pass, equivalent Column and Box hidden-single passes will be implemented symmetrically.