; ***** Routines uit de Graphics.Library
Text= 		-60		; Tekstuitvoer-routine
SetFont= 	-66		; Zet de geladen karakterset aan
CloseFont=	-78		; Sluit de karakterset
Move= 		-240		; Zetten van de grafische cursor
InitBitMap= 	-390		; BitMap initialiseren
InitRastport= 	-198		; Rastport initialiseren
ScrollRaster=	-396		; Scrollen van een stuk Rastport
ClearScreen=	-48		; Scherm schoonmaken

; ***** Routines uit de Exec.Library
AllocAbs=	-204		; Alloceer een stuk geheugen
OpenLibrary= 	-408		; Open een library
CloseLibrary= 	-414		; Sluit een library
Forbid= 	-132		; Verbieden van een interrupt
Permit= 	-138		; Interrupt weer toestaan

; ***** Routines uit de DiskFont.Library
OpenFont=	-30		; Open een karakterset op disk

; ***** Nog wat pointers :
ExecBase=	$04		; Beginadres van de Exec.Library
Scroll=		$55000		; Reserveer geheugen voor scroll.

; ***** Deze routine slaat registers op en allokeert geheugen
Start:	movem.l d0-d7/a0-a6,-(a7)	; Alle registers op de stack zetten
	move.b	#$02,Rows		; 2 in variabele Rows zetten
	move.l	ExecBase,a6		; Exec.lib in A6 zetten
	lea	$50000,a1		; Geheugen op adres $50000 reserve-
	move.l	#8000,d0		;   ren voor 8000 bytes voor de ka-
	jsr	AllocAbs(a6)		;   rakterzet. Roep Alloceer aan

; ***** Deze routine opent de nodige libraries. het adres van de
; ***** library moet worden opgeslagen
        move.l  #0,d0
	lea	GFXName,a1		; Graphics.Library-naam in A1
	jsr	OpenLibrary(a6)		; Open deze library
	beq.L	Error			; Was er een fout ? Dan naar Error
	move.l	d0,GFXBase		; Sla het library-adres op

        move.l  #0,d0
	lea	DiskFontName,a1		; DiskFont.Library-naam in A1
	jsr	OpenLibrary(a6)		; Open deze library
	beq.L	Error			; Was er een fout ? Dan naar Error
	move.l	d0,FontlBase		; Sla het library-adres op

; ***** Lees de karakterset van de diskette
	move.l	FontlBase,a6		; Adres van de DiskFont.Library
	lea	TextAttr,a0		; Struktuur van de karakterzet
	jsr	OpenFont(a6)		; karakterzet laden
	beq.L	Error			; Fout ???
	move.l	d0,FontBase		; Adres van de karakterzet opslaan

; ***** Klaarmaken van de Copperlist voor de kleuren
	lea	Waitab,a0		; CopperLijst met WAIT verlengen
	move.l	#$df09,d1		; Regel $DF - Kolom $09
	move.l	#13,d0			; 14 WAIT's
CoLoop2:
	move.w	d1,(a0)+		; WAIT in de Copperlijst zetten
	move.w	#$fffe,(a0)+		; Alle Bits van WAIT zetten
	move.w	#$0182,(a0)+		; Karakterkleur in Copperlijst
	move.w	#$0fff,(a0)+		; Kleurwaarde
	add.w	#$0100,d1   		; WAIT-waarde 1 regel verder zetten
	dbra 	d0,CoLoop2		; Al 14 keer doorlopen ?

; ***** Multitasking moet uit worden gezet op de Copperlijst te
; ***** verwisselen
	move.l	ExecBase,a6		; Forbid staat in de Exec.Library
	jsr	Forbid(a6)		; MultiTasking verbieden

; ***** Zetten van de nieuwe Copperlijst
	move.l	GFXBase,a0		; Adres van de Graphics.Library
	add.l	#$32,a0			; $32 Optellen voor Copper-adres
	move.w	#$0080,$dff096		; Copper DMA stoppen
	move.l	(a0),OldCopper		; Oude adres opslaan voor later
	move.l	#NewCopper,(a0)		; Nieuwe Copperlijst aanzetten
	move.w	#$8080,$dff096		; Copper DMA starten

; ***** Deze routine maakt een klein scherm waarop de tekst
; ***** straks gaat scrollen. Daarvoor moet een BitMap aange-
; ***** maakt worden
	move.l	GFXBase,a6		; Adres van de Graphics.Library
	lea	BitMap,a0		; Pointer naar de 'nog' lege tabel
	move.l	#$01,d0			; 1 BitPlane
	move.l	#352,d1			; 352 Punten breed
	move.l	#200,d2			; 15 Regels hoog
	jsr	InitBitMap(a6)		; Waarden bitmap initialiseren
	move.l	#$50000,Plane1		; Adres van het grafisch geheugen

; ***** Nu nog de Rastport die deze Bitmap gebruikt
	lea	RastPort,a1		; Pointer naar de 'nog' lege tabel
	jsr	InitRastPort(a6)	; rastport standaardwaarden
	move.l	#BitMap,R_BitMap	; Bitmap-pointer in de rastport
	lea	RastPort,a1		; Karakterzet in de Rastport zetten
	move.l	FontBase,a0		;
	jsr	SetFont(a6)		; Nu het werkelijke zetten

; ***** Wissen van de RastPort
	lea	rastport,a1		; Pointer in A1
	jsr	clearscreen(a6)		; Wissen

; ***** Deze routine zet de scroll aan door de interrupt aan te
; ***** passen. Daarna springen naar de muis-routine
	move.l	#ScrollMsg,C_Ptr	; Beginadres van de tekst zetten
	move.l	$6c,OldIRQ		; Oude IRQ-vektor opslaan
	move.l	#NewIRQ,$6c		; IRQ-vektor van eigen routine
	bra.L	Wait			; Verder naar de muis-routine

; ***** Dit is de nieuwe IRQ-routine. Deze routine verplaatst
; ***** het grafische geheugen steeds met 1 puntje. Daardoor
; ***** lijkt deze te bewegen
NewIRQ:					; Begin NewIRQ-routine
	movem.l	d0-d7/a0-a6,-(sp)	; Alle registers op de stack zetten
	move.l	GFXBase,a6		; Routine in Graphics.Library
	lea	RastPort,a1		; RastPort adres
	move.l	#0,d2			; Links-boven coordinaat
	move.l	#176,d3			; 
	move.l	#352,d4			; Rechts-onder coordinaat
	move.l	#198,d5			; 
	move.l	#$01,d0			; 1 Punt in x-richting schuiven
	clr.l	d1				; 0 Punten in y-richting schuiven
	jsr	ScrollRaster(a6)	; Schuiven !
	sub.b	#$01,Rows		; Al 1 teken ? 16 Puntjes ?
	bne.s	Continue1		; Nee

	move.b	#16,Rows		; Ja
	bsr.s	PrintChar		; Nieuwe letter printen

; ***** Kleurentabel aanpassen zodat het lijkt alsof de kleuren
; ***** lopen. Dit gaat in de Copperlijst na elk puntje
Continue1:
	lea	ColTab,a0		; Kleurentabel verschuiven
	lea	ColTab+2,a1		; 1 Kleur verder (2 bytes)
	move.w	#28,d0			; 28 kleuren
	move.w	ColTab,d1		; Eerste kleur in D1
VerLoop1:
	move.w	(a1)+,(a0)+		; verplaats 2 bytes
	dbra	d0,VerLoop1		; Nog niet klaar dan naar VerLoop1
	move.w	d1,ColTab+56		; Eerste kleur wordt de laatste
	move.l	#13,d0			; 14 Kleuren in de Copperlijst
	lea	ColTab,a0		; Kleurentabel in A0
	lea	WaitAb+6,a1		; Wait-kode in A1
CoLoop1:
	move.w	(a0)+,(a1)		; Verplaats
	add.l	#$08,a1			; 8 Bytes tot de volgende WAIT
	dbra	d0,CoLoop1		; Herhaal
	movem.l	(sp)+,d0-d7/a0-a6	; Registers van de stack af

; ***** Het volgende is een truukje. Omdat de waarde van de oude
; ***** IRQ is opgeslagen kunnen we daar gebruik van maken. De
; ***** volgende instruktie zet het getal erachter letterlijk in
; ***** de code. Dit getal is de machinetaal-code voor JMP. Het
; ***** adres er achter is het opslag-adres van de oude IRQ. In
; ***** feite staat hier dus : JMP OldIQR
	dc.w	$4ef9			; Code voor JMP
OldIRQ:	dc.l	0			; De oude IRQ-vektor
; ***** Deze routine print 1 karakter
PrintChar:
	move.l	GFXBase,a6		; Adres Graphics.Library
	lea	RastPort,a1		; Adres van de RastPort
	jsr	ClearScreen(a6)		; Tussengeheugen wissen
	lea	RastPort,a1		; Adres van de RastPort
	move.l	#320,d0			; Naar x-positie 320
	move.l	#193,d1			; Naar y-positie 14
	jsr	Move(a6)		; Zet de Cursor daar neer
	lea	RastPort,a1     	; Adres van de RastPort
	move.l	C_Ptr,a0		; Karakter vanaf adres C_Ptr
	move.l	#1,d0			; 1 Teken
	jsr	Text(a6)		; Print het teken
	add.l	#$01,C_Ptr		; 1 Bij tekst-pointer optellen
	cmp.l	#Einde,C_Ptr		; Einde van de tekst ?
	bne.s	Return			; Nee
	move.l	#ScrollMsg,C_Ptr	; Begin van de tekst instellen
Return:	rts				; Einde van de tekst-routine

; ***** Wachten tot de linker-muistoets wordt gedrukt
Wait:	btst	#6,$bfe001		; Linker muis-toets gedrukt ?
	bne.s	Wait			; Nee

; ***** De muistoets is gedrukt. Nu moet alles gestopt worden om
; ***** terug te gaan naar AmigaDos
	move.l	OldIRQ,$6c		; Oude IRQ-vektor herstellen
	move.l	GFXBase,a6		; Adres van de Graphics.Library
	move.l	FontBase,a1		; Adres van de karakterzet
	jsr	CloseFont(a6)		; Karakterzet sluiten
	move.l	ExecBase,a6		; Adres van de Exec.Library
	move.l	FontlBase,a1		; Adres van de DiskFont.Library
	jsr	CloseLibrary(a6)	; Sluiten van de library
	move.l	GFXBase,a1		; Adres van de Graphics.Library
	jsr	CloseLibrary(a6)	; Sluiten van de library
	move.l	GFXBase,a0		; Adres van de Graphics.Library
	add.l	#$32,a0			; Plus $32 = Copperlijst
	move.w	#$0080,$dff096		; Copper DMA stoppen
	move.l	OldCopper,(a0)		; Standaard Copperlijst aanzetten
	move.w	#$8080,$dff096		; Copper DMA starten
	move.l	ExecBase,a6		; Adres van de Exec.Library
	jsr	Permit(a6)		; MultiTasking weer toestaan
	movem.l	(a7)+,d0-d7/a0-a6	; Registers van de stack afhalen

Error:	rts				; terug naar de CLI of Seka

; ***** De nieuwe Copperlijst. Hierop kom ik later nog terug.
; ***** Het assembler-kommando "dc.w" betekent zoveel als : ik
; ***** reserveer hier ruimte voor een woord (2 bytes). Dat
; ***** woord (of woorden) staat er achter
NewCopper:
	dc.w 	$0180,$0000		; Zet karakterkleur
	dc.w	$0182,$000a		; Zet achtergrondkleur
	dc.w 	$008e,$2f81		; Links-boven coordinaat
	dc.w	$0090,$f3c1 		; Rechts-onder coordinaat
	dc.w 	$0092,$0038		; DataFetch Start
	dc.w	$0094,$00d0 		; DataFetch Stop
	dc.w 	$0108,$0004		; Modulo voor de grafiek
	dc.w	$010a,$0004		;
	dc.w 	$0102,$0000		; Bitplane-register 1
	dc.w	$0104,$0000 		; BitPlane-register 2
	dc.w 	$0100,$1200		; BitPlane-register 0
	dc.w	$00e0,$0005		; Pointer naar start BitPlane
	dc.w	$00e2,$0000		;
WaitAb:	blk.w	56,0			; 56 Woorden voor de kleuren
	dc.w	$ffff,$fffe		; Einde van de Copperlijst

; ***** Hier komen de verschillende geheugenplaatsen voor
; ***** pointers en teksten. Het assembler-kommando "even" zorgt
; ***** er voor dat alle routines op even adressen beginnen. Dit
; ***** is in een 16-bit-computer noodzakelijk
even

ScrollMsg:				; De te scrollen tekst
	dc.b " Welkom bij dit demo uit AmiGazette nummer 06. U ziet"
        dc.b " hier een demo van het stukje over Assembler.        "
        dc.b " Druk op de linker-muis-knop om deze tekst te stoppen"
        dc.b " en terug te gaan naar de WorkBench.                 "
Einde:
;
even
GFXBase:	dc.l 	0		; Pointer naar de graphics.Library
BitMap:		blk.w 	4,0		; BitMapstruktuur
Plane1:		blk.l 	10,0
RastPort:	blk.l 	1,0		; RastPortstruktuur
R_BitMap:	blk.l 	26,0
OldCopper:	dc.l 	0		; opslag oude Copper
gfxName:	dc.b 	"graphics.library",0
even
diskfontname:	dc.b 	"diskfont.library",0
even
FontName:	dc.b 	"Topaz.font",0
even

; ***** We gebruiken hiet Topaz 11 van de Workbench
TextAttr:	dc.l	fontname	; Adres van de Font-naam
		dc.w	11		; Hoogte in puntjes
		dc.w	0		; Vlaggen
FontlBase:	dc.l	0		; Adres van de DiskFont.Library
FontBase:	dc.w	0		; Adres van de karakterzet
Rows:		dc.w	0		; Aantal gescrollde punten
C_Ptr:		dc.l	0		; Pointer in de tekst

; ***** Nu komen de kleuren. Het format is 0 R G B.
ColTab:		dc.w 	$0ff0,$0cf0,$09f0,$06f0,$03f0,$00f0
		dc.w	$00f3,$00f6,$00f9,$00fc,$00ff,$00cf
		dc.w	$009f,$006f,$003f,$000f,$030f,$060f
		dc.w	$090f,$0c0f,$0f0f,$0f0c,$0f09,$0f06
		dc.w	$0f03,$0f00,$0f30,$0f60,$0f90,$0fc0
