;******  Turbo-Life  ******

ExecBase:      equ   4
FreeMem:       equ   -210
AllocMem:      equ   -198
OldOpenLib:    equ   -408
CloseLib:      equ   -414
CloseScreen:   equ   -66
OpenScreen:    equ   -198
DrawImage:     equ   -114

   move.l   ExecBase,a6
   lea      intname(pc),a1 ; Intuition-Lib
   jsr      OldOpenLib(a6) ; öffnen
   move.l   d0,intbase     ; intbase sichern
   beq      daraus
   move.l   d0,a6
   lea      scrdefs(pc),a0 ; Screen
   jsr      OpenScreen(a6) ; öffnen
   move.l   d0,scrhandle
   beq      noscreen
   move.l   d0,a0
   lea      $c0(a0),a3     ; Plane[0]
   move.l   (a3),a3        ; Start der 1.Bitplane

;****** Feld schwarz färben ******
   lea      $54(a0),a0     ; scr_rastport
   lea      image(pc),a1   ; image
   moveq    #1,d0          ; leftoffset
   moveq    #1,d1          ; topoffset
   jsr      DrawImage(a6)  ;

;****** Speicher reservieren *******
   move.l   ExecBase,a6
   move.l   #256*256,d0    ; Feldgröße
   move.l   #$10000,d1     ; clear
   jsr      AllocMem(a6)
   move.l   d0,feld
   beq      nofeld

   move.l   #100000,d0      ; Stapelgröße
   move.l   #$10000,d1      ; clear
   jsr      AllocMem(a6)
   move.l   d0,stapel1
   beq      nostapel

   move.l   feld(pc),a0    ; feldanfang
   move.l   stapel1(pc),a1 ; Zeiger auf Stapel1
   lea      $6000(a1),a2   ; Zeiger auf Stapel2
   move.l   a2,d7

;*** Tabelle mit Life-Konfiguration auslesen ***
   lea      datas(pc),a0   ; Tabelle
   move     (a0)+,d2       ; xpos
   move     (a0)+,d3       ; ypos
   move     (a0)+,d1       ; y=Anzahl der
   bra.s    einsprung      ; Datenworte
dat0:
   moveq    #15,d0         ; x=Bitposition
   move     (a0)+,d5       ; Datenwort holen
dat1:
   btst     d0,d5          ; Bit=1 (Zelle lebt)?
   beq.s    null           ; nein -> weiter
   moveq    #0,d4
   move.b   d3,d4          ; ypos
   sub.b    d1,d4          ; ykoord=ypos-y
   move.b   d4,(a1)+       ; auf Stapel1
   move     d4,d6          ; ykoord
   move.b   d2,d4          ; xpos
   sub.b    d0,d4          ; xkoord=xpos-x
   move.b   d4,(a1)+       ; auf Stapel1
   mulu     #320,d6        ; \
   add.l    d4,d6          ;  | Zelle bei
   lsr.l    #3,d6          ;  | Position
   not      d4             ;  | (xkoord,ykoord)
   bset     d4,0(a3,d6.l)  ; /  plotten
null:
   dbra     d0,dat1        ; x=x-1
einsprung:
   dbra     d1,dat0        ; y=y-1
   clr      (a1)+          ; Endmarkierung

;******  Hauptroutine  *******
rightmaus:
   btst     #2,$dff016        ; rechte Maustaste
   bne.s    rightmaus         ; Multitasking ade!
   moveq    #0,d4
   moveq    #7,d2
anfang:
   move.l   feld(pc),a0       ; feldanfang
   move.l   stapel1(pc),a1    ; Zeiger auf Stapel1
   move.l   d7,a2             ; Zeiger auf Stapel2
m1:
   move     (a1)+,d0          ; Zelle vom
   beq      abgearbeitet      ; Stapel holen
   ori.b    #$10,0(a0,d0.l)   ; als lebend markieren
                              ; und gleichzeitig
   bmi.s    hop1              ; besuchsflag testen
                              ; gesetzt, dann ->
   move     d0,(a2)+          ; sonst Zelle auf
   bset     d2,0(a0,d0.l)     ; Stapel2 legen und als
hop1:                         ; besucht markieren
   addq.b   #1,d0             ; Nachbarzelle [y,x+1]
   addq.b   #1,0(a0,d0.l)     ; [y,x+1] + 1
   bmi.s    hop2              ; besuchsflag testen
   move     d0,(a2)+          ; Zelle auf Stapel2
   bset     d2,0(a0,d0.l)     ; und markieren
hop2:
   subq.b   #2,d0             ; [y,x-1]
   addq.b   #1,0(a0,d0.l)     ; [y,x-1]+1
   bmi.s    hop3
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop3:
   subi     #256,d0           ; [y-1,x-1]
   addq.b   #1,0(a0,d0.l)
   bmi.s    hop4
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop4:
   addq.b   #1,d0             ; [y-1,x]
   addq.b   #1,0(a0,d0.l)
   bmi.s    hop5
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop5:
   addq.b   #1,d0             ; [y-1,x+1]
   addq.b   #1,0(a0,d0.l)
   bmi.s    hop6
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop6:
   addi     #2*256,d0         ; [y+1,x+1]
   addq.b   #1,0(a0,d0.l)
   bmi.s    hop7
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop7:
   subq.b   #1,d0             ; [y+1,x]
   addq.b   #1,0(a0,d0.l)
   bmi.s    hop8
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
hop8:
   subq.b   #1,d0             ; [y+1,x-1]
   addq.b   #1,0(a0,d0.l)
   bmi      m1
   move     d0,(a2)+
   bset     d2,0(a0,d0.l)
   bra      m1

abgearbeitet:
   move.l   stapel1(pc),a1    ; Zellenstapel restaurieren
   move.l   a2,d3             ; Ende von Stapel2
   sub.l    d7,d3             ; Platzverbrauch
   lsr.l    #1,d3             ; ermitteln
   bra.s    schleifenende
m4:
   move     -(a2),d0          ; nächste Zelle
   move.b   0(a0,d0.l),d1     ; Inhalt holen
   clr.b    0(a0,d0.l)        ; und löschen
   btst     #4,d1             ; bit4=Flag für lebende Zelle
   beq.s    geburt            ; bit4=0 -Zelle ist tot, aber
                              ; Geburt möglich -> Sprung
   cmpi.b   #$92,d1           ; lebende Zelle mit
   beq.s    oberleben         ; 2 Nachbarn -> überlebt
   cmpi.b   #$93,d1           ; lebende Zelle mit
   beq.s    oberleben         ; 3 Nachbarn -> überlebt

;******  Zelle stirbt  ******
   move     d0,d6             ; alle anderen Zellen
   move.b   d0,d4             ; sterben an Überbevölkerung
   lsr      #8,d6             ; oder Vereinsamung
   lsr      #3,d4             ; deshalb
   mulu     #40,d6            ; Zelle 
   add      d4,d6             ; vom
   not      d0                ; Schirm
   bclr     d0,0(a3,d6)       ; löschen
   dbra     d3,m4
   bra.s    schleifenende2
geburt:
   cmpi.b   #$83,d1           ; tote Zelle mit
   bne.s    schleifenende     ; 3 Nachbarn?
   cmpi     #256,d0           ; ja - Zelle wird geboren
   bcs.s    schleifenende     ; falls sie innerhalb
   move.b   d0,d4             ; des 255*255
   beq.s    schleifenende     ; großen Feldes liegt
   move     d0,d6             ;
   lsr      #8,d6             ;
   lsr      #3,d4             ;  plotten
   mulu     #40,d6            ;  der 
   add      d4,d6             ;  Zelle
   not      d0                ;
   bset     d0,0(a3,d6)       ;
   not      d0
oberleben:
   move     d0,(a1)+          ; Stapeln
schleifenende:
   dbra     d3,m4
schleifenende2:
   clr      (a1)              ; Endmarkierung
   btst     #6,$bfe001        ; linke Maustaste
   bne      anfang            ; abfragen
;****** einen guten Abgang machen ******
abgang:
   move.l   ExecBase,a6
   move.l   stapel1(pc),a1    ; Speicher
   move.l   #100000,d0        ; für Stapel
   jsr      FreeMem(a6)       ; zurückgeben
nostapel:
   move.l   ExecBase,a6
   move.l   feld(pc),a1       ; Speicher
   move.l   #256*256,d0       ; fürs Feld
   jsr      FreeMem(a6)       ; zurückgeben
nofeld:
   move.l   intbase(pc),a6
   move.l   scrhandle(pc),a0  ; Screen 
   jsr      CloseScreen(a6)   ; schließen
noscreen:
   move.l   ExecBase,a6
   move.l   intbase(pc),a1    ; Intuition-Lib
   jsr      CloseLib(a6)      ; schließen
daraus:
   rts                        ;  der endgültige Abgang !


intname:    dc.b  "intuition.library",0
   even
scrdefs:    dc.w  0,0,320,256,2
            dc.b  0,1
            dc.w  0,$f
            dc.l  0,0,0,0

scrhandle:  dc.l  0,0
feld:       dc.l  0
stapel1:    dc.l  0
intbase:    dc.l  0
planes:     dc.l  0

image:      dc.w  0,0      ; left,top
            dc.w  255,255  ; width,height
            dc.w  2        ; depth
            dc.l  0        ; imagedata
            dc.b  0,2      ; on,off
            dc.l  0        ; next

datas:
;******  Daten für das r-Pentomino ******
;           dc.w  120,120,3 ; xpos,ypos,Anzahl der
;           dc.w  3,6,2     ; folgenden Datenworte

;******  Daten für das acorn  ******
;           dc.w  140,140,3    ; xpos,ypos,Anzahl
;           dc.w  $20,$08,$67

;******  Daten für die Gleiterkanone  ******
            dc.w  130,130,36   ; xpos,ypos,Anzahl
            dc.w  $0c00,$0c00,0,0,0,0,0,0,0,0
            dc.w  $0e00,$1100,$2080,$2080
            dc.w  0,0,0,0,0,0,0,0,0
            dc.w  $c600,$c600,$0000,$3800
            dc.w  $3800,$1000,0,0,0,0,0
            dc.w  $3000,$3000

   end


