**
** Sortierungsroutine in Assembler
** Straight Selection - Verfahren
**
** PD Asm68k 1.0.3, PD BLINK V6.7 & PD AMIGA.LIB
** FSIH 69          TORNADO 6       TORNADO 6
**
** by Aliso 1989
** ---------------------------------------------

	include	"exec/types.i"		; Macros

** Labels
** ------

MaxLen   equ 18				; max. Länge eines Strings
_SysBase equ $4

	section	Init,Code

_main:

** Dos-Library öffnen
** ------------------

	lea	DOSName,a1		; Name
	CALLSYS	OldOpenLibrary,_SysBase	; öffnen
	move.l	d0,_DOSBase		; Basisadresse merken
	beq.s	1$			; Fehler -> Abbruch

** Output-Handle holen
** -------------------

	CALLSYS	Output,_DOSBase		; Output holen
	move.l	d0,Output		; Adresse merken
	jsr	ShowStrings		; Strings zeigen
	jsr	Sort			; Strings sortieren
	jsr	ShowStrings		; Strings wieder zeigen
	move.l	_DOSBase,a1		; Dos-Library
	CALLSYS	CloseLibrary,_SysBase	; schließen
1$:
	clr.l	d0			; Fehlermeldung v. AmigaDOS
	rts				; und zurück ins AmigaDOS

ShowStrings:
	lea	Begin,a5		; Zeiger auf 1. String
	move.l	MaxAnz,d7		; Anzahl nach D7
	subq.l	#1,d7			; -1
1$:
	move.l	a5,d2			; Zeiger nach D2
	move.l	#MaxLen,d3		; Länge
	move.l	Output,d1		; Output-Handle
	CALLSYS	Write,_DOSBase		; ausgeben

	move.l	#LF,d2			; neue Zeile
	move.l	#1,d3			;
	move.l	Output,d1		;
	CALL	Write			;
	add.l	#MaxLen,a5		; nächster String
	dbf.s	d7,1$			; Schleife
	rts				; und zurück

LF:	dc.b	10,10

** Hauptprogramm der Sortierroutine
** --------------------------------

Sort:
	clr.l	d0			; wir fangen am Anfang an
1$:					;
	cmp.l	MaxAnz,d0		; fertig ?
	beq.s	2$			; ja -> Ende
	bsr	GetMax			; den kleinsten ab (D0)
	addq.l	#1,d0			; nächster String
	bra.s	1$			; Hauptschleife
2$:					;
	rts				; und zurück

** Kopiert einen mit 0 abgeschlossenden String von A0 nach A1
** => A0 Quelle
**    A1 Ziel
** ----------------------------------------------------------

CopyString:
	movem.l	a0/a1,-(sp)		; Register retten
1$:					;
	move.b	(a0),(a1)+		; Byte kopieren
	tst.b	(a0)+			; Ende ?
	bne.s	1$			; nein, weiterkopieren
	movem.l	(sp)+,a0/a1		; Register vom Stack
	rts				; und zurück

** Berechnet den Zeiger auf den in D0 angebenden String
** => D0 Nummer d. Strings
** <= A0 Zeiger auf String
** ----------------------------------------------------

GetString:
	move.l	d0,-(sp)		; Register retten
	lea	Begin,a0		; Array-Beginn
	mulu	#MaxLen,d0		; Offset brechnen
	add.l	d0,a0			; und zuaddieren
	move.l	(sp)+,d0		; Register vom Stack
	rts				; und zurück

** Sucht den kleinsten String ab der in D0 angebenden Nummer und
** trägt ihn in die Liste ein.
** => D0 Nummer
** --------------------------------------------------------------

GetMax:
	movem.l	a0-a6/d0-d7,-(sp)	; alle Register retten
	move.l	d0,Anfang		; Variabeln mit Parameter
	move.l	d0,Kleinster		; beschreiben
1$:					;
	addq.l	#1,d0			; nächster String
	cmp.l	MaxAnz,d0		; alle Strings?
	beq.s	2$			; ja, Ende
	jsr	GetString		; Stringzeiger holen
	move.l	a0,a1			; nach A1
	move.l	d0,-(sp)		; Nummer retten
	move.l	Kleinster,d0		; Nummer d. z.Z. kleins. Str.
	jsr	GetString		; Stringzeiger holen
	move.l	(sp)+,d0		; Nummer vom Stack
	jsr	CMPString		; beide Strings vergleichen
	cmp.l	d7,d6			; Wer hat den größten Wert ?
	bge.s	1$			; kein kleinerer String!
	move.l	d0,Kleinster		; sonst Nummer eintragen
	bra.s	1$			; Schleife
2$:					;
	move.l	Anfang,d0		; Nummer d. Strings nach D0
	jsr	GetString		; Quelladresse berechnen
	move.l	a0,-(sp)		; und retten
	lea	Buffer,a1		; Zieladresse
	jsr	CopyString		; String kopieren
	move.l	(sp)+,a1		; Zieladresse vom Stack
	move.l	Kleinster,d0		;
	jsr	GetString		; Quelladresse berechnen
	move.l	a0,-(sp)		; und retten
	jsr	CopyString		; String kopieren
	move.l	(sp)+,a1		; Ziel
	lea	Buffer,a0		; Quelle
	jsr	CopyString		; String kopieren und fertig!
	movem.l	(sp)+,a0-a6/d0-d7	; Register vom Stack
	rts				; und zurück

** Vergleicht zwei Strings
** => A0 Zeiger auf 1. String
**    A1 Zeiger auf 2. String
** <= D7 Vergleichswert vom 1. String
**    D6 Vergleichswert vom 2. String
** ----------------------------------

CMPString:
	clr.l	d7		; D7 löschen
	clr.l	d6		; D6 löschen
1$:
	move.b	(a0)+,d5	; Zeichen nach D5
	beq.s	2$		; Ende?!
	move.b	(a1)+,d4	; Zeichen nach D4
	beq.s	2$		; Ende?!
	cmp.b	d4,d5		; Zeichen vergleichen
	beq.s	1$		; gleichen -> weitersuchen!
	bgt.s	3$		; 
	addq.l	#1,d6		; D6 erhöhen
	rts			; und zurück
3$:
	addq.l	#1,d7		; D7 erhöhen
2$:				;
	rts			; und zurück

** Variabeln
** ---------
Kleinster:	dc.l	0		; Nummer d. kleinsten Strings
Anfang:		dc.l	0		; 
MaxAnz:		dc.l	25		; Anzahl der Strings
Buffer:		ds.b	MaxLen		; Buffer zum Kopieren

** Beispieldaten
** -------------

Begin:
	dc.b	'Dies ist ein Test',0
	dc.b	'-----------------',0
	dc.b	'Madde            ',0
	dc.b	'Madde I          ',0
	dc.b	'Madde II         ',0
	dc.b	'Franko Friedo    ',0
	dc.b	'Franko Frieda    ',0
	dc.b	'wuerg            ',0
	dc.b	'Wuerg            ',0
	dc.b	'Groß             ',0
	dc.b	'und              ',0
	dc.b	'klein            ',0
	dc.b	'aachen I         ',0
	dc.b	'aachen west      ',0
	dc.b	'Hamburg          ',0
	dc.b	'Hamburger        ',0
	dc.b	'TEST             ',0
	dc.b	'Rudi I           ',0
	dc.b	'Marco            ',0
	dc.b	'Madde            ',0
	dc.b	'Spille           ',0
	dc.b	'Globbe           ',0
	dc.b	'und natuerlich   ',0
	dc.b	'E.U.L.E.         ',0
	dc.b	'-----------------',0
** Ende!!
** ------

DOSName:	dc.b	'dos.library',0
		cnop	2
_DOSBase:	dc.l	0
Output:		dc.l	0
