Single-Step für VC 20
»Single-Step« soll bei Maschinenprogrammen zum Aufdecken von Fehlern beitragen. Anfängern erlaubt es ein schnelleres Einfühlen in die Wirkungsweise der Maschinenbefehle.
Das Programm ist für den Commodore VC 20 mit mindestens 8 KByte Speichererweiterung geschrieben (ein entsprechendes Programm für den C64 finden Sie im 64’er Stammagazin). Es ist ein DATA-Listing einer Maschinenspracheroutine. Über Zeile 9 des Listings läßt sich die gewünschte Startadresse festlegen; die Basic-Schleife ab Zeile 300 korrigiert absolute Sprungadressen. Hierzu wurden bei der Programmerstellung die absoluten Zieladressen so eingestzt, als stünde das Programm ab Adresse 0 im Speicher. Der Basic-Teil sorgt dafür, daß die Startadresse (ss) als Offset berücksichtigt wird.
Nach einmaligem Starten läßt sich die Maschinenspracheroutine mit SYS ss starten, der Basic-Teil kann demnach gelöscht werden, sollte aber sicherheitshalber vorher abgespeichert werden.
Für die Bedienung des Programmes stehen die Funktionstasten F1, F3 und F5 zur Verfügung. Ein Beispiel soll den Ablauf verdeutlichen (Tabelle):
Zunächst startet man »Single-Step« mit SYS ss, es erscheint dann die Überschrift mit Bezeichnung der einzelnen Bildschirmspalten und der ersten, übersetzten Zeile. Nun kann man über F3 in den Editier-Modus gelangen, es lassen sich sämtliche dargestellte Register und Flags ändern. Dazu fährt man mit dem Cursor einfach an die entsprechende Stelle und tippt die gewünschten Werte ein. Im Editier-Modus wird nun der PC (Programm-Counter) so geändert, daß er auf die Startadresse der eigenen Routine zeigt (hier im Beispiel ist dies die Adresse $ 4000). Durch Betätigen der Taste F1 wird der hier abgelegte Befehl ausgeführt. Der PC zeigt dann auf die Startadresse des nächsten Befehles, PSW (Programm Status Word, auch Flag-Register genannt),A,X und Y sind entsprechend verändert. (Im Beispiel wurde der Akku mit den Daten #00 geladen). Jede weitere Betätigung der Funktionstaste F1 bringt einen weiteren Befehl zur Ausführung.
Jetzt noch eine Anmerkung zu Manipulationen im PSW (Flag-Register): Durch Ändern einzelner Flags lassen sich zum Beispiel Schleifen vorzeitig beenden oder, wie im Beispiel in Zeile 16 geschehen, auch verlängern; das Zero-Bit wurde zurückgesetzt, was die CPU durch einen weiteren relativen Sprung auf Adresse $ 4000 quittieren mußte.
Weiterhin lassen sich unter Benutzung des PSW, genauer des I-Flags, Breakpoints im Programm setzen. Es ist nicht immer nötig das Programm schrittweise von Anfang bis Ende zu untersuchen. In solchen Fällen setzt man zu Beginn des interessierenden Teiles den Befehl CLI ein. Es genügt nun im Editiermodus das I-Flag zu setzen und mit F1 den nächsten Schritt zu starten. Das Programm wird erst wieder nach Abarbeiten des CLI- und des darauffolgenden Befehles angehalten.
Die Taste F5 dient zum Ausstieg aus der »Single-Step«-Routine. Ein Betätigen dieser Taste hat die gleiche Wirkung wie Stop/Restore, das heißt es wird eine teilweise Neuinitialisierung und ein Sprung zum Basic-Warmstart durchgeführt.
Abschließend noch eine Anmerkung zur Wirkungsweise:
Ich benutze hier den Timer 1 des VIA 6522 (versatile interface adapter) in der Betriebsart »One-Shot«. Diese läßt sich über das ACR (auxiliary control register) definieren. Der Timer erzeugt jetzt nach jedem Start einen einzelnen Interrupt. Durch geeignete Wahl des Timer-Zählerstandes kann erreicht werden, daß nach jedem Rücksprung aus der Interruptroutine mittels RTI jeweils ein Befehl des zu untersuchenden Programmes ausgeführt wird und darauffolgend die weitere Ablaufsteuerung wieder von der Interruptroutine übernommen wird. Im ersten Hauptteil der Routine »Single-Step« hole ich dann die interessierenden Daten vom Stack und stelle sie auf dem Bildschirm dar. Vor dem Rücksprung mittels RTI wird dann im zweiten Teil die eventuell geänderte Zeile wieder eingelesen und übersetzt.
(Hermann Weißenberger / ev)
0 rem ** hermann weissenberger ** 1 rem tel 09722/2672 2 : 3 rem :::::::::::::::::::::::: 4 rem : ** single - step ** : 5 rem :pc nv-bdizc a x y : 6 rem :::::::::::::::::::::::: 7 : 8 rem startadresse --> ss 9 : ss=24576: rem $6000 10 : 11 rem routine verschiebbar ueber ss 12 : 13 poke56,int(ss/256+.001) 14 poke55,int(ss-256*peek(56)+.001) 15 : 16 rem ********************** 17 rem dataliste der routine (438 byte) 18 : 20 for i=ss to ss+437: read w: poke i,w: next 22 data160,0,185,49,0,32,210,255,200,192 24 data44,208,245,120,173,43,145,41,63,141 26 data43,145,169,93,141,20,3,169,0,141 28 data21,3,169,128,141,138,2,169,20,141 30 data36,145,169,0,141,37,145,88,96,147 32 data32,42,42,32,83,73,78,71,76,69 34 data32,45,32,83,84,69,80,32,42,42 36 data13,80,67,32,32,32,78,86,45,66 38 data68,73,90,67,32,65,32,32,88,32 40 data32,89,13,173,36,145,169,0,72,40 42 data32,46,1,169,13,32,210,255,160,21 44 data169,45,32,210,255,136,16,248,186,160 46 data0,32,57,1,32,57,1,200,32,85 48 data1,200,32,57,1,200,32,57,1,200 50 data32,57,1,32,159,255,32,228,255,201 52 data135,240,44,201,134,240,44,201,133,208 54 data238,186,160,0,32,112,1,32,112,1 56 data200,32,148,1,200,32,112,1,200,32 58 data112,1,200,32,112,1,169,0,141,37 60 data145,104,168,104,170,104,64,120,76,210 62 data254,169,145,32,210,255,160,0,177,209 64 data9,128,145,209,152,72,32,46,1,32 66 data159,255,32,228,255,201,0,240,246,170 68 data104,168,177,209,41,127,145,209,224,133 70 data240,175,224,135,240,207,224,29,240,28 72 data224,157,240,37,224,48,144,206,224,71 74 data176,202,224,58,144,4,224,65,144,194 76 data177,209,41,127,201,45,240,186,138,32 78 data210,255,200,192,22,144,177,169,157,208 80 data5,192,0,240,169,138,32,210,255,136 82 data16,162,160,120,162,221,202,208,253,136 84 data208,248,96,189,6,1,74,74,74,74 86 data32,73,1,189,6,1,41,15,202,201 88 data10,144,2,233,57,105,48,145,209,200 90 data96,189,6,1,72,104,10,72,169,48 92 data144,2,169,49,192,7,240,2,145,209 94 data200,192,13,144,236,104,202,96,177,209 96 data32,139,1,10,10,10,10,157,6,1 98 data200,177,209,32,139,1,29,6,1,157 100 data6,1,200,202,96,201,48,176,2,105 102 data9,41,15,96,189,6,1,41,32,157 104 data6,1,169,128,72,177,209,201,49,208 106 data8,104,72,29,6,1,157,6,1,200 108 data104,74,72,208,236,104,202,96 200 : 205 rem ********************** 210 rem relative plaetze der 215 rem absoluten sprungadressen 220 : 225 data3,101,122,125,129,133,137,141,165 230 data168,172,176,180,184,217,321,371,384 235 data23,28: rem 'interrupt-vektor' 240 : 245 rem ********************** 250 : 300 rem absolute sprungadressen korrigieren 305 : 310 for i=0 to 17 315 : read a 320 : x1=peek(ss+a)+peek(ss+a+1)*256+ss 325 : x2=int(x1/256+.001) 330 : x1=int(x1-256*x2+.001) 335 : poke a+ss,x1 340 : poke a+ss+1,x2 345 next i 350 : 355 read a1:x1=peek(ss+a1) 360 read a2:x1=x1+peek(a2)*256+ss 365 x2=int(x1/256+.001) 370 x1=int(x1-256*x2+.001) 375 poke a1+ss,x1 380 poke a2+ss,x2 385 : 390 rem ********************** 395 : 400 rem belegung der funktionstasten 405 : 410 rem f1 = next step 415 rem f3 = edit-mode 420 : rem akzeptiert werden tasten 0...f und 425 : rem cursor-right,cursor-left 430 rem f5 = ausstieg 435 : 500 print 505 print" start mit:" 510 print"sys";ss 515 end