*---------------------------------------------------------------------
*
* Sieve of Eratosthenes benchmark test published in the September 1981
*   issue of BYTE magazine. This version takes advantage of assembly
*   language optimzations a programmer might make as opposed to trying
*   to write the code a C-compiler might have generated.
*
*   This test runs in 11.85 seconds on a SWTPC 6800, 1 MHz
*
*   Mike Douglas, Jan 2023
*
*---------------------------------------------------------------------
*
* Byte Sieve in C
*
* #define true 1
* #define false 0
* #define size 8190
* #define sizepl 8191
* char flags[sizepl];
*
* main() {
*     int i, prime, k, count, iter;
*     printf("10 iterations\n");
*     for (iter = 0; iter < 10; iter ++) {
*         count=0;
*         for (i = 0; i < sizep1; i++)
*             flags[i] = true;
*         for (i = 0; i < sizep1; i++) {
*             if (flags[i]) {
*                 prime = i + i + 3;
*                 k = i + prime;
*                 while (k < sizep1) {
*                     flags[k] = false;
*                     k += prime;
*                 }
*                 count = count + 1;
*             }
*         }
*     }
*     printf("\n%d primes", count);
* }
*
*-----------------------------------------------------------------------

PDATA1	equ	$E07E			SWTBUG print string
OUT4HS	equ	$E0C8			SWTBUG 16 bit hex display
CONTRL	equ	$E0E3			SWTBUG re-entry point

ITERS	equ	10			repeat test 10 times

* This program REQUIRES the flags table to be at zero

	org	0
flags	rmb	8192
TBLEND	equ	*
ENDMSB	equ	TBLEND/256		MSB of table end address

* Program entry at $2000

start	ldx	#mIters			display "10 iterations"
	jsr	PDATA1
	ldaa	#ITERS			init iteration counter
	staa	iterCnt

* Outer iteration loop

iterLp	dec	iterCnt			count iterations of the test
	bmi	exit			all done

	ldx	#0			set prime count to zero
	stx	count

* Init all flags to true

init	ldx	#flags			X->flags table
	ldaa	#1			non-zero = TRUE

iniLoop	staa	0,x			set all flags true
	inx
	cpx	#TBLEND
	bne	iniLoop

* for (i = 0; i < sizep1; i++) {
*   if (flags[i]) {

	ldx	#flags-1		X->flags table		

tblLoop	inx				move to next table entry
	cpx	#TBLEND			done?
	beq	iterLp			yes, do another iteration

	ldaa	0,x			flag TRUE?
	beq	tblLoop			no

* prime = i + i + 3;

	stx	i			save current value of i
	ldab	i+1			compute i+i
	ldaa	i
	aslb
	rola

	addb	#3			prime=i+i+3
	adca	#0
	stab	prime+1
	staa	prime
	
* k = i + prime, saved in A,B


	addb	i+1
	adca	i

* while (k < sizep1) {
*   flags[k] = false;
*   k += prime;

clrLoop	cmpa	#ENDMSB			past end of table?
	bhs	cntPrim			yes, count the prime

	stab	k+1			flag[k]=FALSE
	staa	k
	ldx	k
	clr	0,x

	addb	prime+1			k=k+prime
	adca	prime
	bra	clrLoop

* count = count + 1;

cntPrim	ldx	count
	inx
	stx	count
	ldx	i			restore X with i
	bra	tblLoop

* Display result and exit

exit	ldx	#mPrimes		display result and exit
	jsr	PDATA1
	ldx	#count
	jsr	OUT4HS
	jmp	CONTRL

*-----------------------------------------------------------
* Data area
*-----------------------------------------------------------
mIters	fcb	13,10
	fcc	"10 Iterations"
	fcb	13,10,10,4

mPrimes	fcc	"Primes found (in hex): "
	fcb	4

i	rmb	2
prime	rmb	2
k	rmb	2
count	rmb	2
iterCnt	rmb	1

	end
