HC680 Assembler ; Quicksort rekursiv 00: ST ; Startadr. Adr Mnm _Op_ _Op_ ; - Kommentar - 00: MOV .SR. .01. ;IO = 01 : Dezimalzahlen in zu sortierender/sortierter Datei 01 INC .A1. :Index für RCL auf 1 02: RCL ;Daten zur Sortierung einlesen, ab Adr. h81 ablegen, Anzahl in D0 03: PSH .D0. ;Anzahl merken 04: LDC .D1. ;lade h80 (Adresse vor Sortierdatenbereich) ... 05: ## 1000 0000 ; 06: ADD .D1. .D0. ; ... + Anzahl gelesener = Endadresse Sortierdaten (unten, Parameter) 07: LDC .D0. ;lade h81 = Anfangsadresse Sortierdaten (oben, Parameter) 08: ## 1000 0001 ; 09: LDC .A0. ;Adr. 17 = h11 für Aufruf Sub Quicksort nach A0 bringen 0A: ## 0001 0001 ; 0B: JSR ;Sprung zum Unterprogramm Quicksort 0C: POP .D0. ;Anzahl Daten holen 0D: CLR .A1. ;Index für STO ... 0E: INC .A1. ;... auf 1 bringen (Sortierte Daten ab h81 im RAM) 0F: STO ;sortierte Daten in Datei schreiben 10: STP ;----- Hauptprogramm anhalten ----- 11: NOP ; / Pivotelement ist unten 12: LDC .A1. ;Sprungdifferenz dez 71 laden <= einelementiger Bereich 13: ## 0100 0111 ; 14: MOV .A0. .D1. ;Adr unteres Element umspeichern für Vergleich 15: SUB .A0. .D0. ;Adressen oben/unten vergleichen 16: DEC .A0. ;(A0)D1 = D0 berücksichtigen (0 -> -1) 17: JIN .+A. ;--- Sprung wenn nur einelementiger Bereich 18: PSH .D0. ;Adr oberes Element merken 19: MOV .A0. .D0. ;obere Adr ins Adressregister (laufender Zeiger oben Zo) 1A: DEC .A0. ;Adr. DEC, da in Schleife erst INC vor Vergleich 1B: PSH .D1. ;Adr unteres Element merken 1C: SSR .D1. ;Adr laufender Zeiger unten (Zu) in Schattenregister bringen 1D: MOV .D1. [D1] ;Wert unteres Pivot-Element (P) laden 1E: PSH .D1. ;Wert P merken 1F: NOP ;<-- Sprungziel äußere Schleife 20: LDC .A1. ;negative Sprungdiff. dez -3 für Schleife laden 21: ## 1111 1101 ;= 22: INC .A0. ;<-- Sprungziel - Adr Zo weiter runter schieben 23: MOV .D0. [A0] ;laufenden oberen Wert laden 24: CMP ;laufenden Wert mit P in D1 vergleichen 25: JIN .+A. ;Schleife bis >= (Fehlplatzierung) 26: MOV .D0. .A0. ;letze Adresse Zo umspeichern 27: SSR .D0. ;Adr Zo merken (Fehlplatzierung) 28: LDC .A1. ;neue Sprungdiff. dez -12 laden 29: ## 1111 0100 ; 2A: GSR .D1. ;Adr Zu holen ... 2B: MOV .A0. .D1. ; ... ins Adressreg. 2C: POP .D0. ;<-- Sprungziel - Wert P nach D0 holen (beachte: umgekehrter Vergleich!) ... 2D: PSH .D0. ;... und wieder merken 2E: DEC .A0. ;Adr Zu weiter hoch schieben 2F: MOV .D1. [A0] ;laufenden unteren Wert laden 30: SUB .D0. .D1. ;Differenz Wert zu Pivotelement 31: PSH .D0. ;Diff. merken (Vorzeichen für Vergleich) 32: MOV .D1. .A0. ;Adr Zu nach D1 bringen 33: SSR .D1. ;letzte Adr Zu merken 34: GSR .D0. ;letzte Adr Zo holen 35: SUB .D0. .D1. ;Differenz Zeiger Zo - Zu 36: POP .D1. ;Differenz Wert zu Pivotelement holen 37: AND .D0. .D1. ; --- Schleifenbed. verknüpfen --- nur Vorzeichen (eine Diff. positiv ) 38: JIN .+A. ;Schleife bis <= Wertvergleich (Fehlplatzierung) oder >= Zeigervergleich 39: LDC .A1. ;--- Abbruchprüfung äußere Schleife Sprungdiff. dez 12 für Schleifenabbruch laden 3A: ## 0000 1100 ; 3B: GSR .D1. ;letzte Adr Zu holen 3C: GSR .D0. ;letzte Adr Zo holen 3D: SUB .D1. .D0. ;Differenz Zeiger umgekehrt Zu - Zo für Abbruchentscheidung 3E: DEC .D1. ;wenn negativ: Zeiger (Adressen) gleich oder überlaufen sich 3F: JIN .+A. ;-> Abbruch der äußeren Schleife 40: NOP ;--- Tausch bei Fehlplatzierung 41: GSR .D0. ;Adr Zo holen 42: GSR .D1. ;Adr Zu holen 43: SWM ;Tausch Werte im RAM: Adr D0 <-> Adr D1 (Zo, Zu) 44: MOV .A0. .D0. ;Zo nach AO 45: POP .D1. ;Wert Pivotel. laden für Vergleich nach Rücksprung 46: PSH .D1. ;und Wert P wieder merken 47: LDC .A1. ;Rücksprungsdiff. dez -42 äußere Schleife in A1 laden 48: ## 1101 0110 ; 49: JMP .+A. ;Rücksprung an Stelle: äußere Schleife (Weiterführung der Vergleiche) 4A: NOP ;--- Ende äußere Schleife --- Tausch Trennelement: 4B: GSR .D0. ;Adr Zo holen (Platz für Trennelement) 4C: POP .D1. ;Wert Pivotel. vom Stack abräumen 4D: POP .D1. ;AdrPivotel. unten laden (dann auch als Parameter) 4E: SWM ;Tausch Werte im RAM: Adr D0 <-> Adr D1 ( Zo <-> Pivot-/Trennelement) 4F: PSH .D1. ;Adr unten wieder merken (Parameter) 50: PSH .D0. ;Adr Trennelement merken 51: INC .D0. ;Adr: Trennel. + 1 (Parameter) 52: LDC .A0. ;Adresse dez 17 = h11 für Rekursion Quicksort laden 53: ## 0001 0001 ; 54: CLR .A1. ;kein weiterer Index für Aufruf 55: JSR ;---> rekursiver Aufruf Quicksort (zuerst rechts) 56: POP .D1. ;Adr Trennelement laden 57: DEC .D1. ;Adr Trennel. - 1 (Parameter) 58: POP .D0. ;Adr unten laden -verwerfen 59: POP .D0. ;Adr oben laden (Parameter) -> Stack abgeräumt! 5A: LDC .A0. ;Adresse dez 17 = h11 für Rekursion Quicksort laden 5B: ## 0001 0001 ; 5C: CLR .A1. ;kein weiterer Index für Aufruf 5D: JSR ;---> rekursiver Aufruf Quicksort (nun links) 5E: RET ;-----> Rücksprung aus Sub Quicksort 5F: NOP ; 60: NOP ;