4/84, S. 88-91

Erste Hilfe

Wem wäre das noch nicht passiert: NEW. Nur drei Buchstaben, aber die Arbeit von Stunden oder gar Tagen ist verloren, wenn das Programm noch nicht gespeichert war. Da hilft dann nur noch eines: das VC 20-Programm »Erste Hilfe«. Laden, starten – und schon ist das gelöschte Programm wieder da. Wie neu!

Flußdiagramm von »Erste Hilfe»

Das grenzt nicht etwa an Zauberei, sondern ist möglich, weil ein Basic-Programm im Speicher des VC 20 mit dem Befehl NEW gar nicht gelöscht wird. Obwohl es nicht den Anschein hat, es ist weiterhin vorhanden. NEW setzt lediglich alle Zeiger zurück und schreibt in die beiden ersten Adressen je eine Null. Will man dem Speicher das nun im Verborgenen liegende Programm wieder entlocken, müssen diese Parameter rekonstruiert werden.

Da wären zunächst die beiden Nullen am Beginn. Sie besagen nichts anderes, als daß sich hier das Programmende befindet. Bei noch vorhandenem Programm enthalten diese Zellen die Koppeladresse zur zweiten Zeile, das heißt, die Speicheradresse, an der diese beginnt. Um sie zu finden, muß in der ersten Programmzeile nach der Null gesucht werden, die das Zeilenende markiert. Plus 1 und die Koppeladresse, zerlegt in Low- und Highbyte, kann wieder am angestammten Platz abgelegt werden. Der zweite Schritt besteht darin, das Programmende wiederzufinden. Mit Hilfe jener Koppeladressen am Beginn jeder Zeile ist auch das relativ einfach. Die erste verrät, wo die zweite steht, diese zeigt auf die dritte und so weiter. Das Programmende ist erreicht, wenn das Highbyte der Koppeladresse eine Null ist. Eine Speicherstelle weiter beginnt dann der Sektor, in dem die Variablen abgelegt werden. Diese Adresse wird dem Computer in den Speicherstellen 45 und 46 mitgeteilt. Der Befehl CLR paßt dann alle übrigen Parameter diesem Wert an. Damit ist das gelöschte Programm wieder da und kann gelistet, bearbeitet, gestartet oder abgespeichert werden.

Da eine solche Rekonstruktion von Hand ein recht mühsames Unterfangen ist, nimmt »Erste Hilfe« dem Anwender diese Arbeit ab. Nicht allein aus Gründen der Geschwindigkeit handelt es sich dabei um ein Maschinenprogramm. Vor allem muß es so in den Speicher gebracht werden, daß es das zu rettende Programm nicht überschreibt und dadurch vollends zerstört. Es ist daher in einem Bereich angesiedelt, in dem sich kein Basic-Programm befinden kann, der aber auch — unabhängig von der gerade verwendeten Speichererweiterung — in jedem Rechner vorhanden ist: die vom System nicht benutzten Adressen von 678 bis 767 auf der Speicherseite 1.

»Erste Hilfe« wirkt immer, selbst bei manipulierter Basic-Untergrenze. Aus den Adressen 43 und 44 ($2B/2C) erfährt das Programm, wo das reparaturbedürftige Obekt beginnt. Das Verfahren nutzt eine Spezialität des 6502-Prozessors: die indirekt-nachindizierte Adressierung. Dabei werden zwei Adressen auf der Zero-Page sozusagen als ein »Briefkasten« benutzt, in dem ein Zeiger auf eine Speicherstelle deponiert wird, deren Inhalt auf diesem (Um-)Weg geladen werden kann. Das geht sehr schnell: Sekundenbruchteile nach dem Start listet sich das wiedererstandene Programm selbst auf dem Bildschirm auf.

Das Programm prüft nicht, ob tatsächlich eine Löschung erfolgt ist. Man kann seine Funktionsfähigkeit also auch an einem intakten Basic-File erproben. Er wird zwar wie ein gelöschter behandelt, aber nicht verändert, da alle Werte so rekonstruiert werden, wie sie im Normalfall auch vorhanden sind. Sollte das aufgelistete Ergebnis Abweichungen vom Urzustand aufweisen, dann sind diese auf irreparable Zerstörungen zurückzuführen. Nach dem versehentlichen Löschen sollten keine Manipulationen mehr vorgenommen werden. Ein LIST-Versuch schadet nicht, aber jede von nun an verwendete Variable überschreibt den ungeschützt im Speicher liegenden File. »Erste Hilfe« kann natürlich nicht erkennen, wenn solche Veränderungen bereits eingetreten sind. Ein Aussprung unter Anzeige eines »Syntax Errors« erfolgt nur, wenn in der ersten Programmzeile nach der maximal zulässigen Zahl von 88 Bytes noch keine End-Null vorgefunden, wurde. So kann es vorkommen, daß sich der Computer in einem weitgehend zerstörten File verirrt und festläuft. Der Verlust durch das notwendige Abschalten ist dann kein allzu großer, denn ein solches Programm wäre ohnehin nicht mehr zu retten gewesen.

Störungen des Programms »Erste Hilfe« sind bisher nur vom Commodore-Modul »Super-Erweiterung« (VC1211A) bekannt. Vor dem Laden des Maschinenprogramms muß dieses Modul durch den im Direktmodus eingegebenen Befehl SYS 64818 abgeschaltet werden, wobei zu beachten ist, daß dadurch ein eventuell heraufgesetzter Basic-Start normalisiert wird und gegebenenfalls wieder angepaßt werden muß, bevor »Erste Hilfe« zur Anwendung kommt.

Assembler-Programmierer können das Maschinen Programm nach dem dokumentierten Listing 1 eingeben und vom Monitor aus abspeichern. Für Basic-Programmierer stehen zwei verschiedene Versionen zur Auswahl. Das als »Kassettenversion« bezeichnete Listing 2 kann auch für die Diskette benutzt werden, wenn die Zeile 110 abgeändert wird in POKE 186,8. Hier wird die Gerätenummer hinterlegt. Die Adressen 187 und 188 enthalten die Adresse des Namens, unter dem das Programm abgespeichert werden soll. Dieser Name ist in der REM-Zeile mit der Nummer 0 abgelegt. Sie ist deshalb unbedingt erforderlich, weil gezielt danach gesucht wird. Die Speicherstelle 183 weist die Länge des Filenamens aus, 185 die Sekundäradresse 1, die dafür sorgt, daß das Programm nicht wie gewöhnlich an den Basic-Start, sondern nach Adresse 678 geladen wird. Von dort aus wird auch abgespeichert: 193/194 enthalten die Startadresse, 174/175 die Endadresse plus 1.

Bei Verwendung einer Diskette kann man sich die vielen POKEs jedoch sparen und die Bytes in Form von ASCII-Codes direkt auf die Floppy schreiben (siehe Listing 3). Dieses Verfahren ist ausschließlich für die Diskette geeignet. Der DATA-Block (Listing 4) ist in beiden Fällen derselbe. Gespeichert werden sollte der File unter dem angegebenen Namen, der die Startadresse enthält, die dadurch nicht in Vergessenheit geraten kann. Für das Laden von Diskette ist LOAD "H*",8,1 einzugeben. Vorteilhafter ist hier das Laden von der Kassette, weil ein einfaches LOAD ohne weitere Angaben genügt. Die Sekundäradresse ist nicht erforderlich, da das Betriebssystem des VC 20 im Bandheader das absolut zu ladende Maschinenprogramm erkennt. Mit SYS 6789 wird dann umgehend »Erste Hilfe« geleistet.

(Helmut Welke)
02A6  A5 2B     LDA $2B      ;Basic-Programmstart Lowbyte
0208  18        CLC
02A9  69 04     ADC #$04
020B  85 FD     STA $FD      ;Zeiger auf Start + 4 setzen
020D  A5 2C     LDA $2C      ;Highbyte
020F  69 00     ADC #$00     ;Carry addieren
02B1  85 FE     STA $FE
02B3  A0 00     LDY #$00     ;Zaehler initialisieren
02B5  B1 FD     LDA ($FD),Y  ;Byte holen
02B7  F0 08     BEQ $02C1    ;Null = Zeilenende?
02B9  C8        INY
02BA  C0 58     CPY #$58     ;88 Bytes geprueft?
02BC  D0 F7     BNE $02B5
02BE  4C 08 CF  JMP $CF08    ;Aussprung mit 'SYNTAX ERROR' (SYS 53000)
02C1  C8        INY
02C2  98        TYA
02C3  A0 00     LDY #$00
02C5  18        CLC
02C6  65 FD     ADC $FD      ;Zaehler + 1 zur Starta.dresse
02C8  91 2B     STA ($2B),Y  ;neue Koppeladresse setzen
02CA  85 FD     STA $FD      ;Zeiger auf 2. Programmzeile
02CC  90 02     BCC $02D0    ;Carry?
02CE  E6 FE     INC $FE      ;Highbyte korrigieren
02D0  A5 FE     LDA $FE
02D2  C8        INY
02D3  91 2B     STA ($2B),Y  ;Koppeladresse high
02D5  88        DEY          ;Zaehler auf Null
02D6  B1 FD     LDA ($FD),Y  ;Koppeladresse zur naechsten Zeile holen
02D8  AA        TAX          ;und retten
02D9  C8        INY
02DA  B1 FD     LDA ($FD),Y  ;Adresse high holen
02DC  F0 07     BEQ $02E5    ;Null = Programmende?
02DE  85 FE     STA $FE      ;Zeiger auf naechste Zeile setzen
02E0  86 FD     STX $FD
02E2  4C D5 02  JMP $02D5    ; und weitermachen
02E5  A5 FD     LDA $FD
02E7  18        CLC
02E8  69 02     ADC #$02
02EA  85 2D     STA $2D      ;Endadresse + 1 = Variablenbeginn
02EC  A5 FE     LDA $FE      ;Highbyte holen
02EE  20 55 C6  JSR $C655    ;Teil des NEW-Befehls (SVS 50754):
                             ;Carry addieren
                             ;Highbyte Variablenspeicher setzen
                             ;CHRGET-Routine auf Programmbeginn setzen
                             ;und Variablen loeschen (CLR: SVS 50782)
02F1  4C 9C C6  JMP $C69C    ;Aussprung mit LIST (SYS 50844)
			
Listing 1. Assemblerprogramm »Erste Hilfe»
0 rem help sys 678
10 printchr$(147)chr$(31)
20 fora=678to755:readb
30 pokea,b:x=x+b:next
40 ifx><10962thenf$="in datas!":goto90
50 a=peek(43)+256*peek(44)+4
60 ifpeek(a)><143goto80
70 a=a+2:ifpeek(a)=72goto100
80 f$="im kopf!"
90 print"fehler "f$:end
100 print"alles ok!":print
110 poke186,1:rem*** kassette ***
120 poke187,aand255:poke188,a/256
130 poke193,166:poke194,2
140 poke174,244:poke175,2
150 poke183,12:poke185,1
500 poke157,128:sys63106
Listing 2. Basic-Lader für die Kassettenversion
10 printchr$(147)chr$(31)
20 fora=678to755:readb
30 pokea,b:x=x+b
40 next:ifx=10962goto90
50 print"fehler in datas!"
60 end
90 print"alles ok!"
100 open1,8,1,"help sys 678"
110 print#1,chr$(166)chr$(2);
200 fora=678to755:b=peek(a)
210 print#1,chr$(b);
250 next:close1
Listing 3. Basic-Lader für die Diskettenversion
1000 data165,43,24,105,4
1001 data133,253,165,44,105
1002 data0,133,254,160,0
1003 data177,253,240,8,200
1004 data192,88,208,247,76
1005 data8,207,200,152,160
1006 data0,24,101,253,145
1007 data43,133,253,144,2
1008 data230,254,165,254,200
1009 data145,43,136,177,253
1010 data170,200,177,253,240
1011 data7,133,254,134,253
1012 data76,213,2,165,253
1013 data24,105,2,133,45
1014 data165,254,32,85,198
1015 data76,156,198
Listing 4. Die gemeinsamen DATA-Werte für die beiden Lader
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →