; ********************************************
; *		 Addperreset 1.2 (13.12.89)			*
; *														*
; * Bindet FastRam waehrend des Resets ein.	*
; * Nur ab Kickstart V1.3 !!!!!!!!				*
; *														*
; *		 Assembler: KICK-ASS V1.25 			*
; *														*
; *	 Written by :	Jörg von Frantzius		*
; *	  Greetings & Thanks to Albert ! 		*
; ********************************************

LN_NAME	= $0A 			  ; Node
LN_PRED	= $04 			  ; (Vorgängerzeiger)

NT_MEMORY	= $0A 		  ; NodeType
ML_NUMENTRIES	= $0E 	  ; MemoryList

ML_ME = $10

ME_ADDR	= 0				  ; MemEntry
ME_LENGTH	= $04

RT_MATCHTAG = $02 		  ; Resident
RT_ENDSKIP	= $06
RT_NAME	= $0E
RT_IDSTRING = $12
RT_INIT	= $16

	; Library-Offsets
OpenLibrary   =	 -552 	 ; exec
SumKickData   =	 -612
Allocmem 	  =	 -198
AddMemList	  =	 -618
KickMemPtr	  =	 546		 ; Pointer in ExecBase
KickTagPtr	  =	 550
KickCheckSum  =	 554
Output		  =	 -60		 ; Dos
IsInteractive =	 -216
Write =	  -48


	move.l  4.s,a6 			 ; ExecBase nach a6

	lea	  dosname,a1		 ; a1 auf Name zeigen lassen
	moveq  #34,d0
	jsr	  OpenLibrary(a6)  ; Library oeffnen
	tst.l   d0					 ; war d0 = 0 ?
	bne	  ok					 ; nein : ok, ist 1.3
	moveq #0,d0 				 ; ja: Dos oeffnen,
	jsr	  OpenLibrary(a6)  ; egal welche Version.
	move.l  d0,dosbase		 ; dosbase retten
	moveq #2,d0 				 ; 3. Text ausgeben: ..
	jsr	  ausgabe			 ; ..falsche Kick-Version
	moveq #0,d0
	rts							 ; beenden
ok:	move.l  d0,dosbase	 ; dosbase retten

	lea	  $200000,a0		 ; moeglicher FastRam Anfang
	move.b  #%10101010,d1	 ; irgendeinen Wert nach d1
suchen:
	move.b  (a0),d0			 ; Byte nach d0 retten
	move.b  d1,(a0)			 ; d1 in Test-Byte schreiben
	move.b  (a0),d2			 ; Byte wieder lesen
	move.b  d0,(a0)			 ; gerettetes Byte zurueck
	cmp.b   d1,d2				 ; geschriebenes=gelesenesByte?
	beq	  gefunden			 ; ja -> FastRam gefunden
	add.l   #$FFFFF/4+1,a0	 ; 256kB weiter gehen
	move.l  a0,d0				 ; a0 nach d0 wegen Flags
	cmp.l   #$A00000,d0		 ; am Ende angekommen ?
	beq	  nichtsda			 ; ja->kein FastRam da, fertig
	bra	  suchen 			 ; nein: weitersuchen
nichtsda:
	moveq #1,d0 				 ; 2. Text ausgeben lassen: ..
	jsr	  ausgabe			 ; .. kein FastMem vorhanden !
	rts
gefunden:
	move.l  a0,a3				 ; Basis von FastRam retten
	jsr	  ende_suchen		 ; Ende von FastRam suchen
	sub.l   a3,a0				 ; FastRamEnde - FastRamBasis ..
	move.l  a0,FastMemLength ; .. ergibt FastRam-Laenge
	move.l  a3,FastMemBasis  ; Laenge+Basis fuer die Reset-
	; -Routine speichern
	move.l  #$10002,d1		 ; d1: CHIP+CLEAR fuer allocmem
	move.l  #BlockEnde-Block,d0 ; Laenge nach d0
	jsr	  Allocmem(a6) 		 ; Speicher belegen
	tst.l   d0						 ; war d0 = 0 ?
	beq	  raus					 ; ja : raus hier
	move.l  d0,Memory 			 ; Adresse retten
	move.l  d0,a1					 ; Zieladresse nach a1
	lea	  Block,a0				 ; Ursprungsadresse nach a0
	move.l  #BlockEnde-Block-1,d0  ; Laenge nach d0
COPY: move.b  (a0)+,(a1)+		 ; ein Byte kopieren
	dbra	  d0,COPY				 ; und nochmal das Ganze

	move.l  Memory,d0 			 ; Adresse von Kopie nach d0
	move.l  Memory,a0 			 ; Adresse von Kopie nach a0
	move.l  d0,RT_MATCHTAG(a0)  ; Matchtag  setzen
	add.l   #Resident_Name-Resident,d0	; Zeiger auf Ende..
	move.l  d0,RT_ENDSKIP(a0)			 ; .. von Resid. setzen
	move.l  d0,RT_NAME(a0)				 ; zugleich Adr. von Name
	add.l   #Resident_Id-Resident_Name,d0	; Zeiger auf Idstring ..
	move.l  d0,RT_IDSTRING(a0) 		 ; .. setzen
	add.l   #addmem-Resident_Id,d0	 ; Zeiger auf	Routine ..
	move.l  d0,RT_INIT(a0)				 ; .. setzen
	move.l  a0,d0							 ; Blockadr. nach d0
	add.l   #MemList-Block,a0			 ; a0: MemList der Kopie
	move.l  a0,MList						 ; Zeiger retten
	move.l  d0,ML_ME+ME_ADDR(a0)		 ; in MemList Zeiger auf
	; zu schuetzenden
	; Speicherblock setzen.
	add.l   #NodeName-Resident,d0  ; Zeiger auf NodeName ..
	move.l  d0,LN_NAME(a0)			 ; .. in MemList setzen
	move.l  Memory,a0 				 ; Adresse der Kopie ..
	move.l  Memory,d0 				 ; .. wieder nach a0 & d0
	add.l   #ResTab-Resident,a0	 ; a0 -> ResTabelle
	move.l  d0,(a0)					 ; ResTab initialisieren
	move.l  a0,RList
	;Memorylist und Resident Tabelle an evtl. vorhandene anhängen

	move.l  KickMemPtr(a6),a0		 ;
	move.l  a0,d0						 ; wegen Flags
	bne	  schon_belegt 			 ; >0: bereits belegt
	move.l  MList,KickMemPtr(a0)	 ; =0: selber belegen
	bra	  TagStuff					 ; bei KickTag weiter
schon_belegt:
	move.l  (a0),d0			  ; ln_Succ holen
	beq	  angekomme 		  ; =0: letzte MemList
	move.l  (a0),a0			  ; <>0: bei der nächsten
	bra	  schon_belegt 	  ; MemList weitermachen
angekommen:
	move.l  MList,(a0)		  ; ln_Succ belegen
	move.l  d0,ml_ln_Pred	  ; eigenen ln_Pred belegen...
	; mit der letzten MemList
TagStuff:
	move.l  KickTagPtr(a6),d0 ; Zeiger auf Tabelle
	bne	  Tag_belegt		  ; <>0: bereits belegt
	move.l  RList,KickTagPtr(a6) ; =0: selber belegen
	bra	  fastfertig			 ; bei Checksumme weitermachen
Tag_belegt:
	move.l  d0,a0				  ; KickTag nach a0
such_Hasso:
	move.l  (a0),d0			  ; Listeneintrag nach d0
	move.l  (a0)+,d1			  ; dito nach d1, und a0 inc.
	beq	  null_gefunden	  ; Endemarkierung gefunden
	and.l   #$80000000,d1	  ; auf Bit 31 testen
	beq	  such_Hasso		  ; nicht gesetzt: weitersuchen
	move.l  d0,a0				  ; war gesetzt: ab Verkettung weiter
	bra	  such_Hasso		  ; weiter suchen
null_gefunden: ; wenn Endemark. gefunden
	move.l  RList,d2			  ; Adr. der eigenen ResTab nach d2
	or.l	  #$80000000,d2	  ; Bit 31 setzen
	subq.l  #4,a0				  ; a0 dec, da ein Eintrag zu hoch
	move.l  d2,(a0)			  ; Verkettungszeiger in bereits vor-
	; handene ResTab eintragen
fastfertig:
	jsr	  SumKickData(a6)   ; Checksum. der  Zeiger berechnen
	move.l  d0,KickCheckSum(a6) ; Checksumme eintragen
	; Checksumme fuer 16 Eintraege der Exec-Base berechnen
	moveq #0,d1 			  ; Zielregister fuer Checksumme
	moveq #$16,d0			  ; 16 Eintraege aus exec-base
	lea	  34(a6),a0 	  ; ab dem 34. Eintrag
sum:
	add.w   (a0)+,d1		  ; auf d1 drauaddieren
	dbra	  d0,sum 		  ; nochmal das Ganze
	not.w   d1				  ; aus Kickstart  (ab $fc043e)
	move.w  d1,82(a6) 	  ; exec-Checksum setzen

	moveq #0,d0 			  ; 1. Text ausgeben lassen: ..
	jsr	  ausgabe		  ; .. alles ok.
raus:
	rts						  ; fertig !

ende_suchen:
	move.b  #%10101010,d1  ; irgendein Wert nach d1
suche_weiter:
	add.l   #$FFFFF/4+1,a0 ; einen 256kB Schritt weiter
	move.l  a0,d0			  ; a0 nach d0 wegen Flags
	cmp.l   #$A00000,d0	  ; schon am Ende angekommen ?
	beq	  ende_gefunden  ; ja : gefunden
	move.b  (a0),d0		  ; Byte aus FastRam retten
	move.b  d1,(a0)		  ; Test-Byte schreiben
	move.b  (a0),d2		  ; Test-Byte wieder lesen
	move.b  d0,(a0)		  ; gerettetes Byte zurueck
	cmp.b   d1,d2			  ; sind beide Test-Bytes gleich ?
	bne	  ende_gefunden  ; nein: Ende von FastRam erreicht
	bra	  suche_weiter   ; ja: immer noch FastRam
ende_gefunden:
	subq.l  #1,a0			  ; Zaehler auf letztes Byte ..
	; .. von FastRam setzen
	rts

Memory:	dc.l	  0	; gerettete Adresse von Speicherblock
MList:	dc.l	  0	; gerettete Adresse der Memory-List
RList:	dc.l	  0	; gerettete Adresse der Resident-Tabelle

ausgabe:
	move.l  d0,d6		; Ausgabe-Nummer retten
	move.l  dosbase,a6		; dosbase nach a6
	jsr	  Output(a6)  ; Ausgabe-handler holen
	move.l  d0,handler  ; handler retten
	move.l  d0,d1		  ; Handler nach d1
	jsr	  IsInteractive(a6) ; testen ob interactive
	tst.l   d0				  ; ist interaktiv ?
	beq	  warnix 		  ; nein: schluss machen
	move.l  dosbase,a6	  ; dos wird gebraucht
	move.l  handler,d1	  ; handler nach d1
	tst.l   d6				  ; war Ausgabe-Nr. <> 0 ?
	bne	  nicht_gefunden ; ja: 2. Text ausgeben
	move.l  #msg,d2		  ; Adr. des 1. Text nach d2
	move.l  #msg_end-msg,d3 ; Laenge des Text nach d3
	jsr	  Write(a6) 	  ; Text ausgeben
	rts						  ; zurueck
nicht_gefunden:
	cmp.l   #2,d6
	beq	  version
	move.l  #msg2,d2		; Adr. des 2. Text nach d2
	moveq  #msg2_end-msg2,d3 ; Laenge des 2. Text nach d3
	jsr	  Write(a6) 	; 2. Text ausgeben
	rts
version:
	move.l  #msg3,d2		; Adr. des 3. Text nach d2
	moveq  #msg3_end-msg3,d3 ; Laenge des 3. Text nach d3
	jsr	  Write(a6) 		 ; ausgeben
warnix:
	rts							 ; zurueck

handler: dc.l	  0
dosbase: dc.l	  0

msg:	dc.b	  $A,'Das FastRam wird beim
						naechsten Reset eingebunden.',$A
	dc.b	  $A,'Wenn FastRam nicht eingebunden
					werden soll : ',$A
	dc.b	  'beim Reset linke Maustaste druecken !',$A,0
msg_end:
msg2: dc.b	  'Konnte kein FastRam finden !',$A,0
msg2_end:
msg3: dc.b	  'Funktioniert nur ab Kick 1.3 !',$A,0
msg3_end:
	even
dosname: dc.b	  'dos.library',0
	even

Block:	; Anfang des zu kopierenden Blockes

Resident:
my_rt_MatchWord:	dc.w	 $4AFC ; Kennung fuer Resident
my_rt_MatchTag:	dc.l	 0 	 ; Zeiger auf Anfang
my_rt_EndSkip: dc.l	 0 		 ; Zeiger auf Ende der Struktur
my_rt_Flags:	dc.b	 %00000001 ; Flags: auszufuehrendes Modul
my_rt_Version: dc.b	 33	 ; Versionsnummer
my_rt_Type: dc.b	 0 		 ; Befehl (ist hier egal)
my_rt_pri:	dc.b	 119		 ; Prioritaet: nach ExecLib
my_rt_Name: dc.l	 0 		 ; Zeiger auf Modul-Name
my_rt_IdString:	dc.l	 0  ; Zeiger auf Erklaerungs-string
my_rt_init: dc.l	 0 		 ; Zeiger auf Anfang von Prg-Code
Resident_Name: dc.b	 'Joergs-addmem-resident',0
	even
Resident_Id:	dc.b	 'Linkt FastRam während des
							  Resets in MemList ein',0
	even
End_of_Resident:

MemList:
ml_ln_Succ: dc.l	 0   ; Node-Eintraege fuer Liste
ml_ln_Pred: dc.l	 0   ;	"     "			"    "
ml_ln_type: dc.b	 10  ; Typ : Memory-Node
ml_ln_Pri:	dc.b	 0   ; Prioritaet egal
ml_ln_Name: dc.l	 0   ; wird nachher eingetragen
My_ml_NumEntries: dc.w	 1 ; Anzahl Eintraege (fuer Bloecke)
ml_me_Addr: dc.l	 0   ; wird nachher eingetragen
ml_me_Length:	dc.l	 BlockEnde-Block
							  ; Laenge des Speicherblocks
NodeName:	dc.b	 'FastMem-Node',0
End_of_MemList:
	even
ResTab:
	dc.l	  0  ; hier wird die Adr. der
					 Resident-Strktr eingetragen
	dc.l	  0  ; die Tabelle MUSS mit 0 abgeschlossen werden

addmem:
	movem.l d0-d2/a0-a5,-(a7) ; Register retten
	btst	  #6,$BFE001		  ; linke Maustaste gedrueckt ?
	beq	  no_mem 			  ; ja: raus hier
	move.l  4.s,a6 			  ; exec-base nach a6
	move.l  FastMemLength(pc),d0 ; d0: Laenge des FastRam
	moveq #5,d1 				  ; d1: Eigenschaft (FAST+PUBLIC)
	moveq #0,d2 				  ; d2: Prioritaet (0 = Fast)
	move.l  FastMemBasis(pc),a0 ; a0: Beginn des FastRam
	lea	  name(pc),a1		  ; a1: Zeiger auf Name
	; Folgende Funktion existiert offiziell erst ab Kick 1.3 !!
	jsr	  AddMemList(a6)	  ; FastRam einbinden lassen
	lea	  $DFF000,a5
	moveq #6,d1 				  ; d1: Zaehler auessere Schleife
	moveq #0,d0 				  ; d0 loeschen
nochens:
	move.w  #$FFF,d0			  ; fff = weiss
immawieda:
	move.w  6(a5),d2			  ; vertikale Strahlenposition
	and.w   #%1111111100000000,d2  ; LSB loeschen
	ror.w   #8,d2				  ; MSB -> LSB fuer Farbregister
	move.w  d2,$180(a5)		  ; ins Farbregister Nr.1 schreiben
	dbra	  d0,immawieda 	  ; d0 erniedrigen und wiederholen
	dbra	  d1,nochens		  ; selbiges mit d1
no_mem:
	movem.l (a7)+,d0-d2/a0-a5; Register zurueckholen
	rts

FastMemBasis:	dc.l	 0 		; Anfang des FastRam
FastMemLength: dc.l	 0 		; Laenge des FastRam

name: dc.b	  'bestes FastRam!',0

	even
AddMemEnd:
BlockEnde:
















































