csieve.c


/*
 *  Eratosthenes Sieve Prime Number Program in from BYTE January 1983
 *
 *  To compile for PicoWeb:
 *
 *     avr-gcc -Os -c -Wa,-alms=csieve.lst -o csieve.o csieve.c
 *
 *  To compile under Linux:
 *
 *     gcc -Os -DMAIN -o csieve csieve.c
 *
 */

#ifdef MAIN
#include <stdio.h>
#else

void putchar(unsigned char ch) {
    /*
     * Note: The PicoWeb AVR assembly language routine "do_putchar" prints
     * out the character passed to it in register r25.  It preserves all of
     * the AVR registers that it uses and therefore call be called directly
     * from C-code.  Because the machine code from the gcc compiler passes
     * int parameters in registers, starting with the register pair r24/r25,
     * "do_putchar" can be called directly from C-code.
     */
    do_putchar(ch<<8);
}
#endif

void putstr(char *s) {
    while (*s) {
        putchar(*s++);
    }
}

void putint(int i) {
    if (i > 9) putint(i/10);
    putchar((i%10) + '0');
}

#define fsize  200
#define size  (fsize*8)
#define FSIZE (fsize+1)

#define TST(buf,n) (buf[(n)>>3]&(1<<((n)&7)))
#define SET(buf,n) (buf[(n)>>3]|=(1<<((n)&7)))
#define CLR(buf,n) (buf[(n)>>3]&=(~(1<<((n)&7))))

unsigned short count;    /* prime counter */
unsigned short flags_bytes = FSIZE;
unsigned short sieve_size;

void sieve(void) {
    unsigned char flags[FSIZE];
    unsigned short i, prime, k;

    count = 0;
    for (i = 0; i <= size; i++)          /* set all flags true */
           SET(flags,i);

    for (i = 0; i <= size; i++)
    {
        if (TST(flags,i)) {          /* found a prime */
           prime = i + i + 3;        /* twice index + 3 */
           putint(prime); putstr(" ");
           for (k = i + prime; k <= size; k+= prime)
               CLR(flags,k);  /* kill all multiple primes found */
           count++;
        }
    }
}

int setsize(void) {   /* this routine must immediately follow sieve() */
    sieve_size = (unsigned char *)setsize - (unsigned char *)sieve;
#ifndef MAIN
    sieve_size = sieve_size << 1;   /* word addresses on AVR processor! */
#endif
}

#ifdef MAIN
main() {
    sieve();
    printf("\n%d primes found\n", count);
    setsize();
    printf("sieve_size = %d\n", sieve_size);
}
#endif

Back