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!

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)
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
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
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