; A segmented Sieve of Eratosthenes for the complete 16-bit address range. ; ; The sieve uses a 256-byte sliding window. Each entry in PrimeStates contains: ; prime, high byte of next multiple, low byte of next multiple ; ; Once a prime becomes active at p*p, adding an 8-bit prime to offsets in a ; 256-byte window must wrap exactly once before the next window. The wrapped ; low byte becomes that prime's starting offset in the following window. ; ; Output is hexadecimal (0002 through FFFD), separated by spaces. #Include Libraries/print.asm #Program start: RSTA SETD Page STA nextPage: ; Clear all 256 flags. A wrapping to zero terminates the loop. SETD Segment RSTA RSTB clearSegment: STB INCD INCA BRA segmentCleared BRI clearSegment segmentCleared: ; Zero and one are not prime. SETD Page LDA BRA excludeZeroAndOne BRI markSegment excludeZeroAndOne: SETD Segment INIA 0x01 STA INCD STA markSegment: ; Process the 54 primes not greater than sqrt(0xFFFF). SETD PrimeStates INIA 0d54 primeLoop: CALL processPrime DPUP 0d03 DECA BRA scanSegment BRI primeLoop scanSegment: ; A is the low byte of the candidate and wraps after 0xFF. SETD Segment RSTA scanLoop: LDB BRB emitPrime scanNext: INCD INCA BRA advancePage BRI scanLoop emitPrime: CALL printCandidateHex BRI scanNext advancePage: SETD Page LDA INCA STA BRA finished BRI nextPage finished: CALL lineFeed HALT ; DP points at a PrimeStates entry on entry and is preserved by CALL. processPrime: PSHD INCD LDA SETD Page LDB XOR BRQ primeIsActive POPD RET primeIsActive: ; Recover and retain the state-entry pointer for the final update. POPD PSHD ; Load the prime into B and its current offset into A. LDA PSHA DPUP 0d02 LDA POPB ; Form Segment + offset. Segment is page-aligned in Data Memory. SETD Segment PSHB PSHD POPB CCF ADD PSHQ POPD POPB markPrimeLoop: INIA 0x01 STA ; Add the prime to the low byte of DP using the stack as a 16-bit ; address adapter. Carry means that the next multiple is in the next page. PSHD POPA CCF ADD PSHQ POPD BRC primeFinished BRI markPrimeLoop primeFinished: ; Q is the wrapped offset for the next page. POPD INCD LDA INCA STA INCD STQ RET ; A contains the candidate's low byte. Page contains its high byte. printCandidateHex: PSHA SETD Page LDA CALL printByteHex POPA CALL printByteHex CALL blankSpace RET #Data ; print.asm deliberately pads its data to one page, so this begins at 0x0100. Segment: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Page: 0x00 PrimeStates: 0x02 0x00 0x04 0x03 0x00 0x09 0x05 0x00 0x19 0x07 0x00 0x31 0x0B 0x00 0x79 0x0D 0x00 0xA9 0x11 0x01 0x21 0x13 0x01 0x69 0x17 0x02 0x11 0x1D 0x03 0x49 0x1F 0x03 0xC1 0x25 0x05 0x59 0x29 0x06 0x91 0x2B 0x07 0x39 0x2F 0x08 0xA1 0x35 0x0A 0xF9 0x3B 0x0D 0x99 0x3D 0x0E 0x89 0x43 0x11 0x89 0x47 0x13 0xB1 0x49 0x14 0xD1 0x4F 0x18 0x61 0x53 0x1A 0xE9 0x59 0x1E 0xF1 0x61 0x24 0xC1 0x65 0x27 0xD9 0x67 0x29 0x71 0x6B 0x2C 0xB9 0x6D 0x2E 0x69 0x71 0x31 0xE1 0x7F 0x3F 0x01 0x83 0x43 0x09 0x89 0x49 0x51 0x8B 0x4B 0x79 0x95 0x56 0xB9 0x97 0x59 0x11 0x9D 0x60 0x49 0xA3 0x67 0xC9 0xA7 0x6C 0xF1 0xAD 0x74 0xE9 0xB3 0x7D 0x29 0xB5 0x7F 0xF9 0xBF 0x8E 0x81 0xC1 0x91 0x81 0xC5 0x97 0x99 0xC7 0x9A 0xB1 0xD3 0xAD 0xE9 0xDF 0xC2 0x41 0xE3 0xC9 0x49 0xE5 0xCC 0xD9 0xE9 0xD4 0x11 0xEF 0xDF 0x21 0xF1 0xE2 0xE1 0xFB 0xF6 0x19