;  Sourcecodedemo fuer Cracker -
; --- Journal Assemblerkurs ----
; Version 2 -  Copper und Grafik
;   (c) 1990 Doctor Mabuse of
;	  Alpha Flight
; ------ Programmadresse -------
jmp		$50000		; Der Programmbeginn wird auf
org		$50000		; $50000 festgesetzt
load		$50000
>extern	"ffff",$70000,$20000	; Vor dem Start des Programmes einmal
				; mit y Befehl Grafik einladen.
; ---------- Offsets -----------
openlibrary= 	-408		; Hier sind vordefinierte Adressen
closelibrary= 	-414		; und Offsets, die wir spaeter
forbid= 	-132		; brauchen werden
permit= 	-138
execbase= 	$04
; ------------------------------
start:
movem.l d0-d7/a0-a6,-(a7)	; Alle Register retten damit am Ende
				; des Programms alles wiederherge-
				; stellt werden kann
; ------------------------------
; -- Graphics Libary oeffnen ---
				; Mit der Exec-Library Funktion
				; Openlibray wird die Graphics
				; Library geoffnet. Dazu holen wir
				; uns die Basisadresse der Offsetliste
move.l	execbase,a6		; aus der Adresse $4=Execbase.
lea	gfxname,a1 	
jsr	openlibrary(a6)		; Die Routine wird angesprungen und
move.l	d0,gfxbase		; wir bekommen als Ergebnis die
				; Adresse der Ofsetliste der GFX-
				; Library. (Etwas Kompliziert)
; -- Multitasking abschalten ---
				; Da der Interrupt der Betriebssystems
				; immer mitlaeuft muessen wir das
move.l	execbase,a6		; Multitasking des Amiga ausschalten,
jsr	forbid(a6)		; was wir hiermit tun.
; ---- Copperfeld erzeugen -----
				; Hier werden die scrollenden Farb-
				; balken vorbereitet. Dabei wird eine
				; Liste mit entsprechenden Copperbe-
				; fehlen mittels der folgenden Schlei-
move.l	#copdat,a0		; fe erzeugt.
move.w	#$2009,d0		; Anfangszeile der Farbbalken laden.
move.w	#$9-1,d1		; Groesse
loop1:
move.l	#colours,a1
move.w	#$20-1,d2
loop2:
move.w	d0,(a0)+		; Copperbefehl 'wait' erzeugen.
move.w	#$fffe,(a0)+ 
move.w	#$0194,(a0)+		; Farbenummer
move.w	(a1)+,(a0)+		; aus Farbliste holen. Die Farbliste
				; steht am Schluss des Programms.
add.w	#$0100,d0		; Wait auf naechste Zeile stellen.
dbra	d2,loop2		; Innere Schleife
dbra	d1,loop1		; Aeussere Schleife
move.w	#$0000,-(a0)		; Letzte Farbe schwarz machen.
; -------- $ffdf,$fffe ---------
move.l	#$ffdffffe,copdat+[[$100-$20]*8]
				; Anstelle des wait $0009,$fffe wird
				; $ffdf,$fffe gesetzt und damit das
				; Copperfeld in den Palbereich gebracht.
; ------ Speicher Loeschen -----
move.l	#$72580,a0
move.w	#$3000,d0
loop3:
move.l	#0,(a0)+
dbra	d0,loop3
; -- Eigene CListe einsetzen ---
move.l		gfxbase,a0
add.l		#$26,a0
move.w		#$0080,$dff096
move.l		(a0),oldcopper
move.l		#newcopper,$dff080
move.w		#$8080,$dff096
; -------- IRQ umbiegen --------
move.w	$dff01c,irqsave		; IRQ Maske speichern
bset	#$f,irqsave		; Spaeteres zurueckschreiben vorbereiten
move.w	#$7fff,$dff09a		; Alle Interrupte abschalten
move.l	$6c,oldirq		; Alten Interrupt speichern
move.l	#newirq,$6c		; Eigenen Vektor reinsetzen
move.w	#$c028,$dff09a		; Erwuenschte Interrupte wieder zulassen
; ------------------------------
;  Hauptprogramm Warteschleife -
				; Jetzt laeuft das Demo nur durch den
main:				; Interrupt. Waehrenddessen wird hier
btst	#6,$bfe001		; auf das Druecken der Mousetaste
bne	main			; gewartet
; ------------------------------
; ------ Abschaltroutine -------
move.l	oldirq,$6c		; IRQ Vektor zurueckschreiben
move.w	irqsave,$dff09a		; Alte IRQ Maske zurueckschreiben
; alte Copperliste wiederholen -
move.w	#$0080,$dff096
move.l	oldcopper,$dff080	; Zurueckschreiben
move.w	#$8080,$dff096
; --- GFX-Library schliessen ---
move.l	execbase,a6		; Mit closelibrary wird die GFX-
move.l	gfxbase,a1		; Library geschlossen.
jsr	closelibrary(a6)
; -- Multitasking einschalten --
move.l	execbase,a6		; Und das Multitasking wieder erlaubt.
jsr	permit(a6)
; ----- Programmaussprung ------
movem.l	(a7)+,d0-d7/a0-a6	; Alle Register zurueckholen und
rts				; verabschieden.
; ------------------------------
; --------- Interrupt ----------
newirq:				; Hier ist Beginn unserer Interrupt-
movem.l	d0-d7/a0-a6,-(sp)	; outine. Zuerst alle Register retten.
; -------- Copperdemo ----------
move.l	#copdat+6,a0		; Mittels dieser einfachen Schleife
move.l	#copdat+14,a1		; werden alle Farbwerte eine Position
move.w	(a0),d0			; nach oben geschoben. Und schliess-
move.w	#9*$20-3,d1		; lich wird der erste Farbwert an die
inter1:				; letzte Stelle gemovet.
move.w	(a1),(a0)
add.w	#8,a1
add.w	#8,a0
dbra	d1,inter1
move.w	d0,(a0)
; --------- Jumproutine --------
add.w	#2,r2
cmp.w	#90*2,r2
bne	j2
move.w	#0,r2
j2:
move.l	#daten,a0
add.w	r2,a0
move.w	(a0),d0
mulu	#88,d0			; Laenge einer Zeile
move.w	#$4000,d1		; Adresse Grundzeile
sub.w	d0,d1
move.w	d1,planes+14		; 1. Bitplane
add.w	#$2c,d1			; Zeilenabstand
move.w	d1,planes+30		; 2. Bitplane
; -- Scrollroutine anspringen --
bsr	scrollroutine
; ------- Interruptende --------
movem.l	(sp)+,d0-d7/a0-a6	; Zuerst die Register zurueckholen
move.w	#$0028,$dff09c		; Interrupt Request Register setzen
rte				; IRQ verlassen
; --------- Register -----------
oldirq:	dc.l	0		; Alter IRQ Vector
irqsave:dc.l	0		; Altes IRQ Maskingregister
r1:	dc.w	0		; Warteregister
r2:	dc.w	0
daten:				; Sprungwerte
dc.w	00,00,00,00,00,01,01,01,01,02,02,02,03,03,04,04,05,06,07,08
dc.w	09,10,12,13,15,17,19,21,23,25,28,30,33,36,39,42,45,48,52,56
dc.w	60,64,68,73,77,81,86,81,77,73,68,64,60,56,52,48,45,42,39,36
dc.w	33,30,28,25,23,21,19,17,15,13,12,10,09,08,07,06,05,04,04,03
dc.w	03,02,02,02,01,01,01,01,00,00,00,00,00,00
; ------- Scrollroutine --------
scrollroutine:
; ----- Verschieberoutine ------
move.l	#$74002+[00*80],$dff050		; Startadresse
move.l	#$74000+[00*80],$dff054		; Destinationadresse
move.l	#$00000000,$dff064		; Kein Modulo, da ganze Breite
move.l	#$ffff1fff,$dff044		; Maske
move.l	#$d9f00000,$dff040		; Kontrollregister
move.w	#[24*2]*64+$16,$dff058		; Hoehe und Breite. Gleichzeitig
					; Startbefehl
wait1:
btst	#6,$dff002			; Blitteroperation abwarten
bne.s	wait1
; ------------------------------
add.w	#3,scroll		; Geschwindigkeit in Pixeln
cmp.w	#27,scroll		; Zeichenabstand in Pixeln
bcs.s	no
move.w	#0,scroll		; Zuruecksetzen
bra.s	printchar		; neues zeichen ausgeben
no:
rts
; ------------------------------
printchar:
clr.l		d0
clr.l		d1
move.l		pointer,a0		; Zeichen holen
move.b		(a0),d0
sub.b		#48,d0			; erstes Zeichen des Zeichensatz
bpl		nnm
move.b		#16,d0			; sonst Leerzeichen
nnm:
move.b		d0,d1
divu		#10,d1			; 20 Character pro Zeile
move.w		d1,d2
swap		d1
move.w		d1,d3
mulu		#4,d3			; 2 Bytes Breit
mulu		#22*80,d2		; 22 Zeilen a 80 Bytes hoch
add.w		d2,d3
move.l		#$70000,d0		; Anfangsadresse Zeichensatz
add.w		d3,d0
move.l		d0,$dff050
move.l		#$74028+[00*80],d0	; Blit Ziel
move.l		d0,$dff054
move.l		#$00240028,$dff064	; Modulo
move.l		#$ffffffff,$dff044	; Maske
move.l		#$09f00000,$dff040	; Modus
move.w		#[22*2]*64+2,$dff058	; Hoehe, Breite und Start
add.l		#1,pointer		; naechstes Zeichen
cmp.l		#ende,pointer
bcs		eee
move.l		#message+0,pointer	; Neuer Start des Scrollers
eee:
wait2:
btst		#6,$dff002	; Warten auf Blitter
bne.s		wait2
rts
; ------------------------------
scroll:		dc.w	0
pointer:	dc.l	message
message:
DC.B	"    JA JUNGS: DAS IST DER SCROLLTEXT:     IMMER DRAN DENKEN; "
DC.B	"NUR GROSSCHRIFT::   1 2 3 4 5 6 7 8 9 0     "
DC.B	"SO LONG FRIENDS::::::::::::                 "
ende:
even				; gerade Adresse garantieren
; ------------------------------
; -------- Copperliste ---------
newcopper:			; Unsere Copperliste
dc.w 	$008e,$4081,$0090,$f0d1 ; linke obere und rechte untere 
				; Koordinaten des BildschirmFenster
dc.w 	$0092,$0038,$0094,$00d0 ; DataFetch Start Stop Register
dc.w 	$0108,$0028,$010a,$0030	; Modulo Werte der Bitplanes
dc.w 	$0102,$0000,$0104,$0040 ; BitPlane Control Reg. #1 u. #2
				; Scrollwerte, Prioritaeten
dc.w 	$0100,$4700		; BitPlane Control Reg. #0
				; 4 Bitplanes + Dual-Playfield
planes:
dc.w    $00e0,$0007,$00e2,$0000	; 1. Plane 1. Field
dc.w	$00e4,$0007,$00e6,$4000	; 1. Plane 2. Field
dc.w	$00e8,$0007,$00ea,$0028	; 2. Plane 1. Field
dc.w	$00ec,$0007,$00ee,$402c	; 1. Plane 2. Field

dc.w	$0120,$0000,$0122,$0000	; alle Sprites abschalten
dc.w	$0124,$0000,$0126,$0000
dc.w	$0128,$0000,$012a,$0000
dc.w	$012c,$0000,$012e,$0000
dc.w	$0130,$0000,$0132,$0000
dc.w	$0134,$0000,$0136,$0000
dc.w	$0138,$0000,$013a,$0000
dc.w	$013c,$0000,$013e,$0000


rgb:
dc.w	$0180,$0000,$0182,$0900	; Farben als RGB-Werte
dc.w	$0184,$0b00,$0186,$0e00
dc.w	$0190,$0990,$0192,$0aa0	; Farben des 2. Fields
dc.w	$0194,$0dd0,$0196,$0ff0
copdat:				; Hier wird der Platz fuer die Liste
blk.w	9*$20*4,0		; unserer Balkenspielerei freigehalten

dc.w	$ffff,$fffe		; Code fuer Ende der Copperliste
; ------ Systemregister --------
gfxbase:	dc.l 	0
oldcopper:	dc.l	0
gfxname:
dc.b 	"graphics.library",0,0
; ---------- Farbliste ---------
colours:			; Hier sind die Farben der Hinter-
				; grundbalken als RGB-Werte abgelegt.
				; Experimentiert ruhig mal ein wenig
				; damit herum.
dc.w	$ff0,$ee0,$ee0,$dd0,$cc0,$bb0,$aa0,$990
dc.w	$880,$770,$660,$550,$440,$330,$330,$220
dc.w	$220,$330,$330,$440,$550,$660,$770,$880
dc.w	$990,$aa0,$bb0,$cc0,$dd0,$ee0,$ee0,$ff0
rot:
dc.w	$f00,$e00,$e00,$d00,$c00,$b00,$a00,$900
dc.w	$800,$700,$600,$500,$400,$300,$200,$100
dc.w	$100,$200,$300,$400,$500,$600,$700,$800
dc.w	$900,$a00,$b00,$c00,$d00,$e00,$e00,$f00
; ----- Programmcode Ende ------
prgend:
