 ****************************************************************************
 *                B O O T R O N      6/1989 von  Michel-Soft                *
 ****************************************************************************
 *   Programmidee und Ausführung von  Michael Schneider, 6490 Schlüchtern   *
 ****************************************************************************
 *         Programm ist Public-Domain   alle Rechte bei Michel-Soft         *
 ****************************************************************************


* benötigte Hardware-Register

AUD1LC		equ		$B0
AUD1LEN		equ		$B4
AUD1PER		equ		$B6
AUD1VOL		equ		$B8
ADKCON		equ		$9E
INTENA		equ		$9A
INTENAR		equ		$1C
INTREQ		equ		$9C
INTREQR		equ		$1E
JOY0DAT		equ		$0A
DMACON		equ		$96
COLOR00		equ		$180
VPOSR		equ		$4
COP1LC		equ		$80
COPJMP1		equ		$88
BPLCON0		equ		$100
BPL1PTH		equ		$E0
BPL1MOD		equ		$108
BPL2MOD		equ		$10A
DIWSTRT		equ		$8E
DDFSTRT		equ		$92
CIAAPRA		equ		$BFE001

* S T A R T

_main		bra		Programm	  ;wg BootBlock
		dc.l		$EB85A94D	  ;Checksumme
		dc.l		$00000370	  ;> Root-Dir
Programm	move.l		4.w,a6		  ;EXEC-Base
		movem.l		a1-a6/d1-d7,-(sp) ;Register retten

* Chip-Ram anfordern
		 
		move.l	#CLsize+16+PRGsize+BPLsize*2+RPsize+MPsize+48,d0 
		move.l		#$10002,d1	;Chip-Ram cleared
		jsr		-198(a6)	;Allocmem
		move.l		d0,a4		;Ram-Adr. auf Stack

* CList ins Chip-Ram

		lea		CLanf(pc),a0	;CList-Adresse
		lea		16(a4),a2	;ChipRam-Adresse
		moveq		#1,d3		;erst CL, dann PRG
		moveq		#CLsize/4-1,d1	;Schleifen-Zähler
CLcopy		move.l		(a0)+,(a2)+	;LWweise kopieren
		dbra		d1,CLcopy	
		lsr.w		#8,d1		;$FF -> d1
		lea		_main(pc),a0	;Adr: PRG-Anf
		dbra		d3,CLcopy	
		
* Playfield initialisieren

		lea		BPL1PTH\w,a0	;HWR für BPL-Adr.
		add.w	#CLsize+16+PRGsize,d0   ;Adr:BPL(0)
		moveq		#1,d2		;Zähler Hauptschleife
a_loop		moveq		#1,d1		;Zähler Nebenschleife
a_loop0		move.w		a0,(a1)+	;HWR in Coplist
		addq.w		#2,a0		;nächstes HWR
		swap		d0		;BPLadr Wort tauschen
		move.w		d0,(a1)+	;unteres Wort in CL
		dbra		d1,a_loop0	;nochmal
		add.w		#BPLsize,d0	;2. Bitplane
		dbra		d2,a_loop	;von vorne

* Bitmap und Rastport initialisieren

		lea		GrName(pc),a1		 ;> GraphLib
		jsr		-408(a6)		 ;OpenLibrary
		move.l		d0,a6			 ;Lib -> a6
		lea		GfxBase(pc),a0		 ;> Basis
		move.l		d0,(a0)			 ;Lib -> Basis
		move.l		a2,BPLsize*2+$6C(a2) 	 ;nach RP_Plane
		add.w		#BPLsize*2+$64,a2	 ;> RP_Bmap
		move.l		#$00280100,(a2)		 ;entspricht
		addq.b		#1,5(a2)		 ; InitBitplane
		lea   CLsize+16+PRGsize+BPLsize*2(a4),a1 ;RPadr
		jsr		-198(a6)		 ;InitRastPort
		move.l		a2,4(a1)		 ;RP_Bmap->RP_Bplane
		move.l		4.w,a6			 ;> Exec-Base

* Messageport einrichten
		
		lea    CLsize+16+PRGsize+BPLsize*2+RPsize(a4),a1 ;MsgPort-Adr
		addq.b		#4,8(a1)	;Typ:MsgPort
		move.l		276(a6),16(a1)	;eigene Task-Adresse
		jsr		-354(a6)	;Addport
		
* Message aufbauen

		move.l		a1,14+MPsize(a1)     ;> MP-Port
		move.w		#48,18+MPsize(a1)    ;Länge der Msg
		move.b		#5,8+MPsize(a1)	     ;Typ:Message	

* Copperlist initialisieren

		lea		$DFF000,a5	       ;HWR-Basisadresse
		move.w		#$7FFF,DMACON(a5)      ;DMA stoppen
		
		move.l		a4,COP1LC(a5)	       ;Adresse der CList
		clr.w		COPJMP1(a5)	       ;Copper starten

		move.l		a4,AUD1LC(a5)	       ;Adresse Sounddaten
		move.w		#SDsize/2,AUD1LEN(a5)  ;Anzahl der Samples

		move.l		#$298129C1,DIWSTRT(a5) ;Fenstergröße
		move.l		#$003800D0,DDFSTRT(a5) ;Anfang DataFetch
		move.w		#$2000,BPLCON0(a5)     ;1 PLF, 2 BPLs
		
		move.w		#$83DF,DMACON(a5)      ;DMA erlauben

* Playfield aufbauen

GAME		move.w		#$2000,-(sp)	  ;Level 3
Screen		lea	CLsize+16+PRGsize(a4),a1  ;BPLadresse
		move.w		#BPLsize-1,d0	  ;Scleifenzähler
delete		clr.w		(a1)+	  	  ;Wortweise clearen
		dbra		d0,delete	  ;
 
Bildaufbau	sub.w		#BPLsize*2-800,a1 ;zur obersten Linie
		moveq		#1,d0		  ;Zähler Hauptschleife
aufbau		moveq		#19,d1		  ;320 Pixel (20 W) Linie
linie		move.w		#$FFFF,(a1)   	  ;Linie oben 
		move.w		(a1)+,8000-2(a1)  ;Linie unten
		dbeq		d1,linie	  ;wiederholen
		move.w		#198,d1		  ;199 Zeilen nur Rand
rand		bset.b		#7,(a1)		  ;linker Rand
		add.w		#39,a1		  ;ans Zeilenende
		addq.b		#1,(a1)+	  ;rechter Rand
		dbra		d1,rand		  ;nächste Zeile
		add.w		#56*40,a1	  ;wieder auf obere Linie
		dbra		d0,aufbau	  ;und nochmal
		bsr		Print
Spielanfang	lea		CLsize+16+PRGsize+4810(a4),a1
		addq.b		#1,(a1)	           ;Anfangspunkt rot
		lea		BPLsize+18(a1),a2  ;Wert lagern
		addq.b		#1,(a2)      	   ;Anfpunkt grün	
		moveq		#0,d2		   ;Anfangs-Punkt
		move.w		#BPLsize,d5	   ;Addier-Register
GetKey		moveq		#-1,d4		   ;WarteSchleife
warte0		dbra		d4,warte0  	   ;warten
		lea		CIAAPRA,a0	   ;CIA-A Basis
		move.b		$C00(a0),d0	   ;ser.Port CIA-A
		cmp.b		#$DF,d0		   ;'Q' gedrückt ?
		beq		ENDE		   ;dann zum CLI
		cmp.b		#$BD,d0		   ;'S' gedrückt ?
		beq		Disk_IO		   ;dann saven
		cmp.b		#$AF,d0		   ;´L´ gedrückt ?
		bne		start		   ;wenn nicht

level		lea		string4+2(pc),a3   ;LevelZahl
		cmp.b		#"0",(a3)	   ;LeZa ´0´ ?
		bne		le00		   ;wenn größer
		move.w		#$2900,(sp)	   ;Verzögerungswert
		addq.b		#4,(a3)		   ;LeZa ´4´
le00		sub.w		#$0900,(sp)	   ;akt.Verzwert -$900
		subq.b		#1,(a3)		   ;akt.LeZa -1
		bra		Screen

start		cmp.b		#63,(a0)	   ;beide Feuerknöpfe
		bhi		GetKey		   ;wenn nicht
		jsr		-132(a6)	       ;Forbid
		move.w		#64,AUD1VOL(a5)	   ;Pump up the Volume!
		
Joystick0	move.w		JOY0DAT(a5),d0	  ;Register für Port0
		moveq		#1,d6		  ;Flag für JoyAbfrage
		btst		#6,(a0)		  ;Feuerknopf gedrückt?
		bra		Joy1		
Joystick1	move.w		JOY0DAT+2(a5),d0  
		moveq		#0,d6
		btst		#7,(a0)
Joy1		bne		Joy2		  ;wenn nicht gedrückt
		moveq		#1,d4		  ;sonst Schleife 2mal
		move.w		#1490,AUD1PER(a5) ;hoher Ton
		bra		Joy3		  
Joy2		moveq		#0,d4		  ;Schleife 1mal 
		move.w		#2980,AUD1PER(a5) ;tiefer Ton
Joy3		move.l		a1,a3	  	  ;a1 zwischenspeichern
		move.l		a2,a1		  ;glagerter Wert -> a1
		move.l		a3,a2	  	  ;Wert lagern
		neg.w		d5		  ;BPLsize = -BPLsize
		swap		d3		  ;JoymitteReg. drehen
		swap		d2		  ;PositionsReg. drehen
Joy4		btst		#1,d0		  
		bne		joy_rechts
		btst		#9,d0
		bne		joy_links
		move.w		d0,d1
		lsr.w		#1,d1
		eor.w		d0,d1
		btst		#0,d1
		bne		joy_rueck
		btst		#8,d1
		bne		joy_vorn

joy_mitte	tst.b		d3		;Test: je nach
		beq		joy_links	; Wert in d3.w
		cmp.b		#2,d3		; Verzweigung
		bmi		joy_rechts	; in die versch.
		beq		joy_rueck	; Bewegungsauswertprogs


joy_vorn	move.w		#3,d3		;Flag für Joy_Mitte
		sub.w		#40,a1		;eine Zeile hoch
		bra		Fahrt		
		
joy_links	clr.w		d3		;Flag für Joy_Mitte
		addq.b		#1,d2		;zum nächsten Bit
		cmp.b		#8,d2		;Überlauf im Byte ?
		bne		Fahrt		;wenn nicht
		clr.b		d2		;sonst Bit8 = Bit0
		subq.w		#1,a1		;und ein Byte weniger
		bra		Fahrt		

joy_rechts	move.w		#1,d3
		subq.b		#1,d2
		tst.b		d2
		bge		Fahrt
		move.b		#7,d2
		addq.w		#1,a1
		bra		Fahrt

joy_rueck	move.w		#2,d3
		add.w		#40,a1

Fahrt		
		btst		d2,(a1)		;Bit schon gesetzt ?
		bne		Crash		;wenn ja : CRASH!!!
		btst		d2,0(a1,d5.w)	;Bit schon gesetzt ?
		bne		Crash		;wenn ja : CRASH!!!
		bset		d2,(a1)		;setzen eines Punktes
		dbra		d4,Joy4		;durch FEUER schneller
		
wait		move.w		(sp),d7       	;Geschwindigkeit(Level)
verzug		dbra		d7,verzug	;Verögerung des Spiels
JoyAbfrage	tst		d6		;welcher Joystick
		beq		Joystick0	; ist an der Reihe?
		bra		Joystick1	; Joy0 oder Joy1 ?
		
* Auswertung eines Zusammenstoßes
		
Crash		clr.w		AUD1VOL(a5)	  ;Stille!!!
		jsr		-138(a6)	   ;Permit
		lea		string2(pc),a0	  ;Crashzahl(rot)
		tst		d6		  ;Spieler1 ?
		bne		zwei	 	  ;wenn ja
eins		addq.l		#6,a0		  ;Crashzahl(grün)
zwei		addq.b		#1,(a0)		  ;Zahl erhöhen
		cmp.b		#9+48,(a0)	  ;9 Crashes ?
		bne		Screen		  ;wenn weniger
Auswert		bsr		Print		  ;
		move.l		#$00180000,d7     ;Verzögerung 
warte1		subq.l		#1,d7		  ;nach
		bne		warte1		  ;Spielende
		lea		string2(pc),a0	  ;Crashzahl(rot)
		move.b		#48,(a0)	  ;wieder ´0`
		move.b		(a0),6(a0)	  ;CrZa(grün) ´0`
		bra		Screen		  

* alte Copperlist starten, Speicher zurückgeben und Programm beenden

ENDE		addq.l		#2,sp		   ;SP auf Ursprung
		move.w		#$000F,DMACON(a5)  ;Soundkanäle löschen
		lea		GfxBase(pc),a1	   ;Name der Graphics.Lib
		move.l		(a1),a1
		move.l		38(a1),COP1LC(a5)  ;alte Coplist-Adr.
		clr.w		COPJMP1(a5)	   ;starten
		move.w		#$83E0,DMACON(a5)  ;alte DMAs ein
		jsr		-414(a6)	   ;CloseLibrary  
		
		lea		CLsize+16+PRGsize+BPLsize*2+RPsize(a4),a1
		jsr		-360(a6)	   ;Remport

		move.l	#CLsize+16+PRGsize+BPLsize*2+RPsize+MPsize+48,d0 
		move.l		a4,a1	   	   ;Ram-Adresse
		jsr		-210(a6)	   ;Freemem

		lea		DosName(pc),a1	   ;> DosLib
		jsr		-96(a6)		   ;FindResisdent
		move.l		d0,a0		   
		move.l		22(a0),a0		
		moveq		#0,d0		   ;kein Fehler
		movem.l		(sp)+,a1-a6/d1-d7  ;Register holen
		
		rts				   ;E N D E

* Disketten-Aktionen

Disk_IO		lea  CLsize+16+PRGsize+BPLsize*2+RPsize+MPsize(a4),a1 ;> MSG
		lea		DevName(pc),a0  ;> TD-Device
		moveq		#0,d0		;Drive=DF0:
		moveq		#0,d1		;keine Flags
		jsr		-444(a6)	;OpenDevice
Disk_Write	move.w		#3,28(a1)       ;Befehl:Write
		lea	CLsize+16(a4),a2 	;> Anfang der
		move.l		#$444F5300,(a2) ;für BootBl. ´DOS´,0
		move.l		a2,40(a1)       ; Daten im Ram
		move.w		#2*512,38(a1)   ;Anzahl der Blks		
		jsr		-456(a6)	;DoIO
		move.w		#4,28(a1)	;Track beschreiben
		jsr		-456(a6)	;DoIO
Disk_Stop	move.w		#9,28(a1)	;Befehl:Motor 
		clr.l		36(a1)		; ausschalten
		jsr		-456(a6)	;DoIO
		jsr		-450(a6)	;CloseDevice
		bra		Screen		;zum Menü

* Subroutines
 
Print		lea		text1(pc),a0		;Adr: ´BOOTRON´
		bsr		Pr00			;Ausdrucken
		lea		text2(pc),a0		;Adr: ´0´
		bsr		Pr00
		lea		text3(pc),a0		;Adr: ´0´
		bsr		Pr00
		lea		text4(pc),a0
		
Pr00		lea		GfxBase(pc),a6		;> GfxLib
		move.l		(a6),a6			; nach a6
		lea  CLsize+16+PRGsize+BPLsize*2(a4),a1	;Adresse des RPorts
		moveq		#0,d0			;löschen
		move.w		(a0)+,d0		;X-Pos
		moveq		#0,d1			;löschen
		move.b		(a0)+,d1		;Y-Pos
		jsr		-240(a6)		;Move
		move.b		(a0)+,d0		;TextLen
		jsr		-60(a6)			;Text
		move.l		4.w,a6
		rts

* Variablen und Konstanten 

GfxBase		ds.l		1
GrName		dc.b		"graphics.library",0
		even
DosName		dc.b		"dos.library",0
		even
DevName		dc.b		"trackdisk.device",0
		even

BPLsize		equ		40*256
SDsize		equ		16
RPsize		equ		$64+$08+$20
MPsize		equ		34
PRGsize		equ		1024

* Copperlist
		
CLanf		dc.w		COLOR00,$0000,COLOR00+2,$0F00
		dc.w		COLOR00+4,$00F0,COLOR00+6,$0FFF
		dc.w		$FFFF,$FFFE
CLsize		equ		*-CLanf

* Texte

text1		dc.l		$00000F17	;Textposition codiert
string1		dc.b		"BOOTRON  by Michel-Soft",0
		even
text2		dc.l		$0053E701
string2		dc.b		"0",0
		even
text3		dc.l		$00E3E701
string3		dc.b		"0",0
		even
text4		dc.l		$0092E703
string4		dc.b		"L:3",0
		even

		END
