| |
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
|
|
|