#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

#define NUMSTARS 30

static UBYTE   *padr1[NUMSTARS];
static UBYTE   *padr2[NUMSTARS];
static UBYTE    maske[NUMSTARS];
static UBYTE    c[NUMSTARS];
static int      p[NUMSTARS];
static BOOL     last[NUMSTARS];
extern LONG     maxadr1;
extern PLANEPTR base1,base2;

	
ClearStars()

{
 register int i;

 for (i = 0; i < NUMSTARS; i++)
     last[i] = FALSE;
}
   

InitStars()

{
 int i,x,y;
 
 for (i = 0; i < NUMSTARS; i++)
     {
      x = (320 / NUMSTARS * i);
      y = Random(111)*Random(31);
      y = y % 256;
      maske[i] = 1 << (7-(x & 0x07));
      padr1[i] = (UBYTE*)(base1 + (LONG)(x/8) + (LONG)(320/8 * y));
      padr2[i] = (UBYTE*)(base2 + (LONG)(x/8) + (LONG)(320/8 * y));
      c[i] = (UBYTE)Random(3)+1;
      do {
      p[i] = (Random(17) * Random(19)) % 7 +1;
      } while (p[i] == p[i-1]);
      p[i] = p[i] * 40;
      last[i] = FALSE;
     }
}

DeleteStars()

{
 register int i;
 register UBYTE *p;
  
 for (i = 0; i < NUMSTARS; i++)
     {
      if (!last[i])
         continue;
      p = padr1[i];
      *p &= (~maske[i]);
      p = padr2[i];
      *p &= (~maske[i]);
     }
}

WriteStars()

{
 register int i;
 register UBYTE *p1;
 register UBYTE *p2;
 register UBYTE s1,s2;
 
 for (i = 0; i < NUMSTARS; i++)
     {
      p1 = padr1[i];
      p2 = padr2[i];
      s1 = (*p1 & maske[i]);
      s2 = (*p2 & maske[i]);
      if ((s1 == (UBYTE)0) && (s2 == (UBYTE)0)) 
         {
          last[i] = TRUE;
      	  switch(c[i]) {
      	    case 0 : break;
      	    case 1 : *p1 |= maske[i];
      	             break;
      	    case 2 : *p2 |= maske[i];
      	             break;
      	    case 3 : *p1 |= maske[i];
      	             *p2 |= maske[i];
      	             break;
      	}
      }
     else last[i] = FALSE; 
     }
}

MoveStars()

{
 register int i;

 DeleteStars();

 for (i = 0; i < NUMSTARS; i++)
     {
      padr1[i] += (LONG)p[i];
      padr2[i] += (LONG)p[i];
      if ((LONG)(padr1[i]) >= maxadr1) {
      	 padr1[i] -= 10240L;
      	 padr2[i] -= 10240L;
      }
     }
 WriteStars();
}

#asm
;--------------------------------------------------------------------	
	even

Interrupt:
	dc.l	0			;letzter Node
	dc.l	0			;nächster Node
	dc.b	2			;Node Type = Interrupt
	dc.b	0 			;Priorität
	dc.l	InterruptName		;Name
	dc.l	0			;Zeiger auf Daten
	dc.l	IntCode			;Interrupt Routine
CiaBBase:
	dc.l	0
DosBase:
	dc.l	0
DelayValue:
	dc.w	21000

Datensegment:
	dc.l	0
InterruptName:
	dc.b	"Star Interrupt",0
	even
CiaBResource:
	dc.b	'ciab.resource',0
	even
DosLib:
	dc.b	'dos.library',0
	even

; Program follows...


	
	even
	
	Public	_StartStars,_StopStars



_StartStars:
	movem.l	d1-d7/a0-a6,-(SP)
	lea	Datensegment,a1
	move.l	a4,(a1)
	move.l	4,a6			;ExecBase
	lea	CiaBResource,a1		;'ciaB.resource'
	moveq	#0,d0			;Version egal
	jsr	-498(A6)		;OpenResource()
	lea	CiaBBase,a2
	move.l	d0,(a2)			;Resource Base speichern
	move.l	d0,a6
	cmp.l	#0,d0
	beq	EndStart
	lea	Interrupt,a1		;Stars Interupt Structure
	moveq	#0,d0			;TimerA
	jsr	-6(A6)			;installieren
	move.l	d0,d5			;ergebnis speichern
	bsr	InitTimer
	moveq	#0,d0			;Ergebnisregister loeschen
	tst.l	d5			;ergebnis von Resource
	sne	d0			;ergebnis in d0 setzen 
EndStart:
	movem.l	(SP)+,d1-d7/a0-a6
	rts

;---------------------------------------------------------------------------

_StopStars:
	movem.l	d1-d7/a0-a6,-(SP)
	lea	CiaBBase,a6
	move.l	(a6),a6			;Zeiger auf CiaB Resource
	cmp.l	#0,a6
	beq	EndStop
	lea	Interrupt,a1		;Zeiger auf Int. Strukture
	moveq	#0,d0			;Timer A
	jsr	-12(A6)			;Interupt entfernen
EndStop:
	moveq	#0,d0			;Alles Ok	
	movem.l	(SP)+,d1-d7/a0-a6
	rts

InitTimer:
	move.b	#%10000001,$bfde00	;Timer starten
	lea	DelayValue,a1
	move.b	1(a1),$bfd400		;Timer A low
	move.b	0(a1),$bfd500		;Timer A high
	rts
	
IntCode:
	movem.l	d1-d7/a0-a6,-(SP)
	lea	Datensegment,a1
	move.l	(a1),a4
	bsr	_MoveStars
	moveq	#0,d0
	movem.l	(SP)+,d1-d7/a0-a6
	rts	
;---------------------------------------------------------------------------
#endasm
