//
//         SIEVE OF ERATOSTHENESE
//
// PRIME NUMBER FINDER SHOWING OFF SOME
// OF PLASMA'S BIT MANIPULATION
// OPERATIONS.
//
// THE APPLE ][ CANNOT DISPLAY THE
// TWO SYMBOLS USED FOR BIT COMPLIMENT
// AND INCLUSIVE OR: THE TILDE AND THE
// BAR. SO ALIASES FOR THESE OPERATORS
// ARE:
//
//    ~ : BITWISE COMPLIMENT   (CTRL-Y)
//    | : BITWISE INCLUSIVE OR (CTRL-B)
//
// ON THE APPLE ][, THESE SHOW UP AS AN
// INVERTED ^ AND AN INVERTED \.
//
// IN THIS EXAMPLE, AN ARRAY IS USED TO
// HOLD THE FLAGS USED TO IDENTIFY NON-
// PRIME VALUES. THIS IS MORE MEMORY
// EFFICIENT THAN USING A WHOLE BYTE FOR
// EACH FLAG, BUT REQUIRES BITWISE TESTS
// FOR ONE OF THE EIGHT FLAGS IN EACH
// BYTE. SHIFTING RIGHT IS A FAST WAY
// TO DIVIDE BY POWERS OF TWO:
// X >> 3 IS THE SAME AS X / 8
// SHIFTING LEFT IS A FAST WAY TO
// MULTIPLY BY POWERS OF TWO:
// X << 2 IS THE SAME AS X * 4
//

CONST FALSE  = 0
CONST TRUE   = NOT FALSE
CONST IMAX   = 8192
CONST IMAXM1 = IMAX-1
CONST SIZEF  = IMAX/8
CONST CR     = $0D

BYTE[SIZEF] FLAGS
WORD PRIME, I, K, COUNT = 0

MEMSET(@FLAGS, 0, SIZEF)
FOR I = 0 TO IMAXM1
  IF NOT (FLAGS[I >> 3] & (1 << (I&7)))
    PRIME = I + I + 3
    FOR K = PRIME + I TO IMAXM1 STEP PRIME
      FLAGS[K >> 3] = FLAGS[K >> 3] | (1 << (K&7))
    NEXT
    COUNT = COUNT + 1
    PUTI(PRIME)
    PUTC(CR)
  FIN
NEXT
PUTI(COUNT)
PUTS(" PRIMES BETWEEN 0 AND ")
PUTI(IMAX << 1)
DONE
