Die besten Tips und Tricks
Es ist einfach lästig, immer wieder -zig Hefte nach einem bestimmten Trick durchsuchen zu müssen. Deshalb haben wir die wichtigsten und interessantesten Tips und Tricks aus früheren 64'er-Ausgaben für Sie zusammengestellt.
Teilweiser Nachdruck aus 64'er Sonderheft 1/85, S. 94 (nur die Tips »Basic-Programme retten«, »Cursor steuern«, »Cursor beschleunigt«, »Directory ohne Programmverlust«, »Commodore-Joystick verbessert«, »Sequentielle Datei als Basic-Programm laden«, »Spezialeffekt«, »VC 20-Grundversion simuliert«, »Zwei Tips für den C 64« und »Und noch ein Tip«), 64'er 12/84, S. 85 (nur der Tip »List- und Löschschutz leichtgemacht«) und 64'er 6/85, S. 80 (nur die Tips »Directory ohne Programmverlust«, »Commodore-Joystick verbessert«, »Sequentielle Datei als Basic-Programm laden«, »Zwei Tips für den C 64« und »VC 20-Grundversion simuliert«). Die übrigen Tips stammen nicht aus diesen Ausgaben.
Kennen Sie folgende Situation? Man sitzt vor einem Programmierproblem und erinnert sich – da stand doch mal was bei den Tips und Tricks. Ein Stapel 64'er wird geholt, und die Sucherei geht los. Wir wollen da Abhilfe schaffen. Auf den folgenden Seiten finden Sie unter anderem kurze Programme zu den Themen: Basic-Programme retten und verbinden, Bildschirm speichern, Cursor steuern, Listschutz, Maschinenprogramme speichern, PET-Simulation, Reset-Hilfen.
Basic-Programme verbinden
So manch einen C 64-Besitzer wird es schon geärgert haben, daß sein Computer keinen MERGE-Befehl besitzt. Mit wenig Aufwand ist es aber dennoch möglich, Basic-Programme aneinanderzuhängen:
- Im Direktmodus »PRINT PEEK(43); PEEK(44)« eingeben und sich die Ergebnisse merken.
- Das erste Programm normal laden.
- Erscheint jetzt nach »PRINT PEEK(45)« eine Null oder eine Eins, dann geben Sie »POKE 43, 256 + PEEK(45) - 2 : POKE 44, PEEK(46) – 1 : NEW« ein. Im anderen Fall wird »POKE 43, PEEK(45) - 2 : POKE 44, PEEK(46) : NEW« eingegeben.
- Nun wird das anzuhängende Programm geladen (Achtung! Das anzuhängende Programm muß die höheren Zeilennummern haben).
- Jetzt POKEn Sie in die Speicherstellen 43 und 44 die zu Anfang gemerkten Werte.
Beide Programme sind nun verbunden. Wichtig bei der ganzen Prozedur ist, daß keine Variablen definiert werden, da das MERGEn sonst nicht richtig funktioniert.
(Thomas Lopatic)Basic-Programme retten
Die Betriebssystemroutine »Angleich von Koppeladressen« ab Adresse 42291 ermöglicht ein schnelles und einfaches »UNNEW« nach einem versehentlichen »NEW« oder Reset:
POKE 2049,1 : POKE 2050,1 : SYS 42291
Danach kann zumindest wieder geLISTet werden. Ein vollständiges »UNNEW« verlangt allerdings die Korrektur der Zeiger auf den Beginn der Variablen und Felder. Dazu wäre die Kenntnis der Programmlänge notwendig. Man kann sich aber behelfen, indem man das Programm notfalls in Teilen auf dem Bildschirm auf LISTet und die einzelnen Zeilen mit der RETURN-Taste neu übernimmt.
(Gerhard Wagner)UNNEW
Haben Sie ein Programm versehentlich mit NEW gelöscht, hilft UNNEW:
100 FOR I=525 TO 578
120 READ A : POKE I,A : NEXT I
200 POKE 43,525 AND 255 : POKE 44,2
210 POKE 45,578 AND 255 : POKE 46,2
220 CLR : SAVE " UNNEW",8 : REM bzw. ,1,1
300 DATA 160,003,200,177,043,208,251,200
310 DATA 200,152,160,000,145,043,165,044
320 DATA 200,145,043,133,060,160,000,132
330 DATA 059,162,000,200,208,002,230,060
340 DATA 177,059,208,245,232,224,003,208
350 DATA 242,200,208,002,230,060,132,045
360 DATA 164,060,132,046,096,256
Wenn Sie dieses Programm eingeben und starten, wird ein Programm namens »UNNEW« auf Diskette geschrieben. Falls Sie aus Versehen NEW eingetippt haben, dann laden Sie das Programm durch
LOAD "UNNEW" ,8,1
und starten es durch
SYS 525
Bildschirm auf Kassette/Diskette
Das kurze Maschinenprogramm (Listing 1) dient dazu, den Bildschirminhalt beim Commodore 64 zu speichern und auch wieder einzuladen. Dies kann mit einem Recorder oder Diskettenlaufwerk geschehen. Dabei werden außer dem eigentlichen Bildschirmspeicher (der an eine beliebige Stelle verschoben sein kann und nicht ab Adresse 1024 liegen muß) auch das Color-RAM und die Tabelle der Doppelzeilenkennzeichnungen mitberücksichtigt. Das Speichern und Laden erfolgt über einen Pufferbereich im »versteckten« RAM ab 40960, da die drei verschiedenen Speicherbereiche in einem Stück gespeichert und außerdem die 1000 Farbnibbles zu 500 Bytes zusammengeschoben werden. Das erspart beim Arbeiten mit dem Recorder wertvolle Zeit.
Nach dem Eintippen des Basic-Loaders kann durch »RUN 16« geprüft werden, ob es richtig eingegeben wurde. Trotzdem sollte es vor dem Start gespeichert werden, da auch durch Prüfsummen nicht alle Fehler erkannt werden können. Ausgegeben werden zwei Adressen für das Laden und Speichern. Das Programm kann an jede Stelle des Arbeitsspeichers geladen werden, in der vorliegenden Version lädt es sich an das Ende des Basic-Arbeitsspeichers. Es ist davon auszugehen, daß das Programm direkt nach dem Einschalten ohne andere Erweiterungen geladen und gestartet wird.
Soll ein Bildschirminhalt auf Diskette gespeichert werden, so erfolgt dies durch
SYS 40738 "FILENAME", 8
Beim Arbeiten mit Recorder kann (auch beim Laden) die Gerätenummer entfallen; die Angabe einer Sekundäradresse ist nicht erlaubt. Durch das Speichern bedingte Betriebssystemmeldungen wie »PRESS RECORD & PLAY« sowie das Scrolling des Bildschirms sind unbedeutend und werden nicht berücksichtigt. Alle Bildschirmdaten werden zuvor in einen Zwischenspeicher übertragen.
Das Laden solcherart gespeicherter Bildschirminhalte geschieht mit
SYS 40833 "FILENAME", 8
Zunächst werden die Daten in den Puffer von Adresse 40960 bis 42483 geladen und dann in MSB-Tabelle, Farbspeicher und die momentan gewählte Videomatrix übertragen.
(Ralph Babel)0 rem screensaver 64
1 d=55:a=peek(56)*256+peek(d)-222:gosub4:clr:s=peek(56)*256+peek(55)
2 for i=stos+221:reada:pokei,a:next:a=s+173:d=s+1:gosub4:d=s+96:gosub4
3 print"{down}save:"s:print"load:"s+95:end
4 poked,a-int(a/256)*256:poked+1,a/256:return
5 data32,,,162,4,177,7,145,9,200,208,249,230,8,230,10,202,208,242,162,24,181
6 data217,157,231,163,202,208,248,162,218,202,202,134,8,177,7,41,15,133,11,232
7 data232,134,8,177,7,10,10,10,10,5,11,145,9,200,208,229,230,10,224,219,208,224
8 data169,160,133,8,165,1,72,41,254,133,1,169,7,162,244,160,165,32,216,255,170
9 data104,133,1,138,176,1,96,76,249,224,32,,,169,,32,213,255,176,243,165,1,72
10 data41,254,133,1,162,4,160,,177,9,145,7,200,208,249,230,8,230,10,202,208,242
11 data162,24,189,231,163,149,217,202,208,248,162,218,202,202,134,8,177,9,145,7
12 data232,232,134,8,74,74,74,74,145,7,200,208,235,230,10,224,219,208,230,104
13 data133,1,96,32,87,226,162,1,32,121,,240,3,32,241,183,160,2,32,186,255,173,
14 data221,73,3,133,8,173,24,208,41,240,70,8,106,70,8,106,133,8,160,,132,7,132
15 data9,169,160,133,10,96
16 clr:forq=.to221:reada:x=a+x:y=a-y:next
17 print"{down}checksum "mid$("error ok",1-5*(x=27349andy=-217),5):end
Cursorsteuerung leichtgemacht
Bei professionellen Programmen der PC-Klasse kann der Cursor meist über Eingabegeräte wie die Maus positioniert werden. Daß es auch recht gut mit dem Joystick und dem C 64 funktioniert, beweist dieses Programm.
Haben Sie den kurzen MSE-Lader (Listing 2) eingetippt und gestartet, können Sie den Cursor mit einem Joystick in Port 2 steuern. Das Steuerprogramm befindet sich von Adresse $C000 bis $C066 im Speicher. Die ersten 15 Bytes nimmt eine Initialisierungsroutine in Anspruch, die den Interruptvektor auf $C00F legt und das Steuerprogramm in den Kernelinterrupt einbindet. Die Routine wird mit SYS 49152 aufgerufen. Das Programm benutzt Speicherzelle $02 als Zählregister, da der Joystick nur bei jedem sechsten Interrupt abgefragt wird. In Zeile 300 des Assemblerlistings (Listing 3) wird die Zählvariable um 1 erniedrigt. Ist die Variable 0, wird sie auf 6 gesetzt und in die Steuerungsroutine verzweigt. Ab Zeile 360 wird der Tastaturpuffer auf freien Platz überprüft. Sollte der Puffer voll sein, wird sofort in die Interruptroutine des Betriebssystems ($EA31) gesprungen. In Zeile 400 wird der Joystick abgefragt und das entsprechende Cursorsteuerzeichen in den Akku geladen. Ab 800 wird das Zeichen in den Tastaturpuffer geschrieben und der Pufferzeiger erhöht.
(P. Siepen)PROGRAMM : CURSOR C000 C068 ----------------------------------- C000 : A9 0F 8D 14 03 A9 C0 8D B2 C008 : 15 03 A9 06 85 02 60 C6 41 C010 : 02 F0 03 4C 31 EA A9 06 F2 C018 : 85 02 A6 C6 E0 08 90 03 B7 C020 : 4C 31 EA AD 00 DC 29 01 03 C028 : C9 00 D0 05 A9 91 20 5E 2A C030 : C0 AD 00 DC 29 02 C9 00 2C C038 : D0 05 A9 11 20 5E C0 AD 6B C040 : 00 DC 29 04 C9 00 D0 05 63 C048 : A9 9D 20 5E C0 AD 00 DC C7 C050 : 29 08 C9 00 D0 05 A9 1D 06 C058 : 20 5E C0 4C 31 EA A6 C6 F4 C060 : 9D 77 02 E6 C6 60 00 C0 07
10 REM*********************************
20 REM* CURSOR STEUEREUNG *
30 REM* *
65 REM* PETER SIEPEN *
70 REM* *
75 REM* VON-STEPHAN-STR.6 *
80 REM* *
82 REM* 4200 OBERHAUSEN 1 *
84 REM* *
85 REM* TELEFON :(0208)/26555 *
90 REM*********************************
95 :
100 SYS9*4096
110 .OPT P,00
111 :
112 :
113 :
114 :
120 *= $C000
125 :
130 :
140 :
150 TEST = $02 ;ZAEHLVARIABLE
160 JOY = 56320 ;PORT #2
170 AZITP = $C6 ;ANZAHL ZEICHEN IM PUFFER
174 :
175 :
180 LDA #<BEGINN;INTERUPTVEKTOR
185 STA $314
190 LDA #>BEGINN;AUF NEUE
195 STA $315 ;ADDRESSE SETZEN
200 LDA #$06 ;ZAEHLVARIABLE
205 STA TEST ;HOCHSETZEN
210 RTS ;ZURUECK ZU BASIC
215 :
220 :
225 :
300 BEGINN DEC TEST
320 : BEQ START ;GENUG LEER IRR
330 : JMP $EA31 ;NEIN WEITER MIT IRR
340 START LDA #$06 ;ZAEHLVARIABLE HOCHSETZEN
350 : STA TEST
360 : LDX AZITP ;TASTATURPUFFER
370 : CPX #$08 ;VOLL
380 : BCC WEITER
390 : JMP $EA31 ;JA WEITER MIT INTERUPT
400 WEITER LDA JOY ;WENN JOY NICHT
410 : AND #1 ;NACH OBEN
420 : CMP #0 ;WEITER
430 : BNE NOBEN
440 : LDA #"{UP}" ;WENN JA STEUERZEICHEN
450 : JSR AUSG ;AUSGEBEN
460 NOBEN LDA JOY
470 : AND #2
480 : CMP #0
490 : BNE NUNTEN
500 : LDA #"{DOWN}"
510 : JSR AUSG
520 NUNTEN LDA JOY
530 : AND #4
540 : CMP #0
550 : BNE NLINKS
560 : LDA #"{LEFT}"
570 : JSR AUSG
580 NLINKS LDA JOY
590 : AND #8
600 : CMP #0
700 : BNE NRECHTS
710 : LDA #"{RIGHT}"
720 : JSR AUSG
730 NRECHTS JMP $EA31
740 :
750 :
760 :
770 :
780 :
790 :
800 AUSG LDX $C6 ;X-REG FUER
810 : STA $277,X ;INDIZIERTE
820 : INC AZITP ;ADDRESSIERUNG
830 : RTS ;LADEN
840 : ;IN TASTPUFFER
850 : ;SCHREIBEN
860 : ;ANZAHL ZEICHEN
870 : ;IM TASTPUFFER
880 : ;ERHOEHEN
890 :
900 :
READY.
Cursor steuern
Das Betriebssystem des C 64 enthält eine Routine, die man benutzen kann, um den Cursor an eine beliebige Stelle zu setzen. Geben Sie doch mal folgendes ein:
POKE 214, (Zeile) : POKE 211, (Spalte) : SYS 58640 : PRINT " TEXT"
(Michael Keukert)
Cursor beschleunigt
Für alle diejenigen C 64-Besitzer, denen die Bewegung des Cursors bisher zu langsam war, gibt es einen speziellen POKE.
Mit POKE 56325,5 wird der Cursor rasend schnell und flitzt bei Betätigung der Cursortasten nur noch so über den Bildschirm. Wer's lieber gemütlicher mag, der sollte es statt dessen einmal mit POKE 56325,255 probieren.
(Oliver Bausch)Directory ohne Programmverlust
Häufig möchte man sich das Directory einer Diskette ansehen, ohne das gerade im Speicher befindliche Programm zu zerstören. Wenn man das DOS 5.1 nicht geladen hat, behilft man sich meist mit der zeitaufwendigen Zwischenspeicherung des Programms auf der Diskette. Es geht jedoch auch einfacher und schneller. Geben Sie einfach den folgenden Befehl ein:
POKE 44, PEEK(46) + 1
Damit wird der Basic-Anfang auf einen freien Speicherbereich gestellt. Sie können jetzt wie gewohnt mit »LOAD "$",8« das Directory laden und anschließend auflisten.
Mit POKE 44,8 sind Sie dann wieder im eigentlichen Programm.
(Heinzpeter Oelkers)Floppy-Lister
Mit einem einfachen SYS-Aufruf können Sie Programme und sequentielle Dateien direkt von Diskette listen. Programme im Speicher bleiben dabei erhalten.
»Floppy-Lister« bietet zwei Möglichkeiten, ein Programm von Diskette zu listen. Basic-Programme und sequentielle Dateien können entweder als Klartext oder als Speicherauszug (Dumps) gelistet werden. Im Dumpmodus werden sämtliche Daten als Hexcodes ausgegeben und, soweit möglich, in ASCII-Zeichen übersetzt. Deshalb eignet er sich besonders zum Analysieren von unbekannten Programmdateien. Maschinenprogramme dürfen grundsätzlich nur auf diese Art gelistet werden, will man einen Absturz vermeiden.
Ist das Ladeprogramm (Listing 4) mit dem MSE eingetippt, kann das Maschinenprogramm auf Diskette oder Kassette gespeichert werden. Der »Floppy-Lister« kann dann direkt geladen (LOAD "name", 8, 1, oder LOAD "name", 1, 1) und mit SYS 49152,"XY:filename" aufgerufen werden. Vergessen Sie nach dem absoluten Laden nicht, den erforderlichen NEU-Befehl im Direktmodus einzugeben, um die Basic-Zeiger in einen vernünftigen Zustand zu bringen. »X« steht für die Fileart: entweder »P« für Programm oder »S« für sequentielle Datei. »Y« steht für den Modus, in dem gelistet werden soll: »L« für einfaches Listen und »D« für Ausgabe in Form eines Speicherauszugs. Zum Beispiel listet der Befehl SYS 49152,"SL:TESTSEQUENZ" eine sequentielle Datei mit dem Namen »TESTSEQUENZ«. Abkürzungen des Filenamens mit »*« sind erlaubt. Falsche Eingaben werden mit einer Fehlermeldung quittiert.
Mit der CTRL-Taste kann die Ausgabe verlangsamt und mit der RUN/STOP-Taste unterbrochen werden. Eine Fortsetzung erfolgt mit der A-, und vorzeitiger Abbruch des Listens mit der DEL-Taste. Am Ende eines Listings muß immer die SPACE-Taste gedrückt werden.
Das Maschinenprogramm für »Floppy-Lister« liegt im Bereich von $C000 -$C2B2 (49152-49842). An das Programm schließt sich noch ein Pufferbereich an, wo Daten zwischengespeichert werden. "Floppy-Lister" läuft mit den gängigen Erweiterungen, wie DOS 5.1, Simons Basic und Exbasic.
(B. Schulzki)PROGRAMM : FLOPPYLISTER C000 C2B5 ----------------------------------- C000 : 20 FD AE 20 9E AD 20 A3 EE C008 : B6 A5 64 85 A7 A5 65 85 A3 C010 : A8 A0 00 B1 A7 99 1F C3 8A C018 : C8 C0 03 90 F6 AD 1F C3 F4 C020 : C9 14 B0 1E C9 04 90 24 2A C028 : A0 00 AD 21 C3 85 A8 AD BE C030 : 20 C3 85 A7 B1 A7 99 22 8B C038 : C3 C8 CC 1F C3 D0 F5 4C A9 C040 : 53 C0 A9 6F A0 C2 20 1E 28 C048 : AB 4C 74 A4 A9 88 A0 C2 B2 C050 : 4C 46 C0 A2 00 BD 22 C3 42 C058 : 8D 1E C3 C9 50 F0 08 C9 5F C060 : 53 D0 E9 A0 04 D0 02 A0 BA C068 : 00 E8 BD 22 C3 C9 4C F0 2E C070 : 06 C9 44 D0 D7 C8 C8 E8 3F C078 : BD 22 C3 C9 3A D0 CD 8C EB C080 : 0E C3 AE 1F C3 A9 2C 48 CA C088 : 9D 22 C3 E8 AD 1E C3 9D 5A C090 : 22 C3 68 E8 9D 22 C3 A9 18 C098 : 52 E8 9D 22 C3 A9 00 E8 65 C0A0 : 9D 22 C3 EE 1F C3 AD 28 34 C0A8 : 03 8D 0F C3 AD 29 03 8D F9 C0B0 : 10 C3 A9 22 8D 28 03 A9 CA C0B8 : C2 8D 29 03 AD 1F C3 A2 14 C0C0 : 25 A0 C3 20 BD FF A9 02 B1 C0C8 : A2 08 A0 02 20 BA FF 20 EF C0D0 : C0 FF A2 02 20 C6 FF AC 0A C0D8 : 0E C3 B9 AB C2 8D 11 C3 10 C0E0 : B9 AC C2 8D 12 C3 6C 11 65 C0E8 : C3 A9 00 8D 13 C3 8D 14 DF C0F0 : C3 8D 15 C3 A2 00 20 0F 00 C0F8 : C2 B0 03 4C E9 C1 20 CF 29 C100 : FF 9D 16 C3 A5 90 D0 05 F8 C108 : E8 E0 08 90 E9 8D 15 C3 5B C110 : A9 00 E8 E0 08 B0 07 9D 6D C118 : 16 C3 E8 4C 13 C1 20 4C 2C C120 : C2 AD 14 C3 20 2A C2 AD F0 C128 : 13 C3 20 2A C2 A9 3A 20 0D C130 : D2 FF A2 00 BD 16 C3 20 86 C138 : 23 C2 E8 E0 08 90 F5 20 30 C140 : 4C C2 A9 12 20 D2 FF A2 78 C148 : 00 BD 16 C3 29 7F C9 20 1B C150 : B0 04 A9 2E D0 03 BD 16 7B C158 : C3 20 D2 FF E8 E0 08 90 B7 C160 : E8 A9 0D 20 D2 FF AD 15 72 C168 : C3 D0 11 18 AD 13 C3 69 30 C170 : 08 8D 13 C3 90 03 EE 14 81 C178 : C3 4C F4 C0 4C E9 C1 20 12 C180 : 51 C2 20 51 C2 A2 FF 20 E6 C188 : 51 C2 A5 A7 E8 9D B3 C2 68 C190 : E0 03 90 F3 20 51 C2 E8 FE C198 : A5 A7 9D B3 C2 D0 F5 E8 4B C1A0 : 9D B3 C2 E8 9D B3 C2 A9 BA C1A8 : B3 85 5F A0 C2 84 60 20 1C C1B0 : 37 A5 AD 00 03 48 AD 01 50 C1B8 : 03 48 A9 22 8D 00 03 A9 C6 C1C0 : C2 8D 01 03 20 C3 A6 68 75 C1C8 : 8D 01 03 68 8D 00 03 20 C9 C1D0 : 0F C2 B0 B1 4C E9 C1 20 FE C1D8 : CF FF 20 D2 FF A5 90 D0 1A C1E0 : 08 20 0F C2 B0 F1 4C E9 B4 C1E8 : C1 20 CC FF A9 02 20 C3 9F C1F0 : FF AD 0F C3 8D 28 03 AD 84 C1F8 : 10 C3 8D 29 03 A9 60 A0 B3 C200 : C2 20 1E AB A5 CB C9 3C 28 C208 : D0 FA A9 00 85 C6 60 A5 1B C210 : CB F0 0E C9 3F D0 08 A5 F6 C218 : CB F0 06 C9 0A D0 F8 38 92 C220 : 60 18 60 48 A9 20 20 D2 6F C228 : FF 68 48 4A 4A 4A 4A 20 17 C230 : 42 C2 A8 68 29 0F 20 42 1B C238 : C2 48 98 20 D2 FF 68 4C B0 C240 : D2 FF 18 69 F6 90 02 69 14 C248 : 06 69 3A 60 A9 20 4C D2 10 C250 : FF 20 CF FF 85 A7 A5 90 A0 C258 : F0 05 68 68 4C E9 C1 60 CE C260 : 0D 20 20 20 20 12 20 53 43 C268 : 50 41 43 45 20 0D 00 0D 57 C270 : 46 45 48 4C 45 52 3A 20 05 C278 : 4E 41 4D 45 20 5A 55 20 CD C280 : 4C 41 4E 47 20 21 0D 00 29 C288 : 0D 46 45 48 4C 45 52 3A BF C290 : 20 46 41 4C 53 43 48 45 A8 C298 : 53 20 45 49 4E 47 41 42 1F C2A0 : 45 46 4F 52 4D 41 54 20 97 C2A8 : 21 0D 00 7F C1 E9 C0 D7 5E C2B0 : C1 E9 C0 32 A9 0F
Joystickabfrage:
Auch die Joystickabfrage ist beim C 64 nicht ganz einfach. Dabei hilft folgendes Hilfsprogramm:
10 POKE 56322,224
20 JO=PEEK(56320)
30 IF (JO AND 1)=0 THENPRINT"OBEN"
40 IF (JO AND 2)=0 THENPRINT"UNTEN"
50 IF (JO AND 4)=0 THENPRINT"LINKS"
60 IF (JO AND 8)=0 THENPRINT"RECHTS"
70 IF (JO AND 16)=0 THENPRINT"FEUER"
Dieses Programm gilt für eine Joystickabfrage am Controlport 2.
Commodore-Joystick verbessert
Der Commodore-Joystick VIC-1311 benötigt eine relativ große Hebelbewegung, um die Kontakte zu schließen. Bei Spielen, die eine hohe Reaktionsgeschwindigkeit erfordern, ist diese Eigenschaft sehr ungünstig. Man kann jedoch recht einfach Abhilfe schaffen:
Man entfernt die vier Schauben an der Unterseite des Gehäuses und hebt den oberen Teil des Joysticks mit der Platine vorsichtig ab. Nun wird die Platine an den Durchtrittsöffnungen der Schrauben mit je einer etwa 1 Millimeter dicken Unterlegscheibe verstärkt. Die vier Unterlegscheiben können mit einem Tropfen Alleskleber (Vorsicht, nicht die Kontakte verkleben!) gegen Verrutschen gesichert werden. Danach wird der Joystick wieder zusammengeschraubt. Wenn Sie alles richtig gemacht haben und insbesondere keine Teile übriggeblieben sind, dann werden die Kontakte des Joysticks nun bei erheblich kleineren Hebelbewegungen geschlossen.
(M. Kunze)List-Schutz für Basic-Programme
Dieser List-Schutz (Listing 5) ist für Nichteingeweihte sehr verblüffend. Die Grundidee dazu stammt aus dem Bericht »Disketten-Manipulationen« aus der 64'er, Ausgabe 6/85. Er wurde jedoch etwas ausgebaut, so daß hier beim Listen alle Steuercodes aktiv werden. Dies wird dadurch erreicht, daß man in eine Speicherstelle vor den Codes die Zahl 141 schreibt. Um nun ein Programm zu schützen, lädt man es und gibt zwei Zeilen ein (Listing 5).
Danach gibt man im Direktmodus ein:
POKE 2067,71 : POKE 2073,141 : POKE 2118,0 :
POKE 2119,0
Listet man nun das Programm, so wird der Bildschirm gelöscht und der Text in der REM-Zeile ausgegeben. Durch das künstlich erzeugte Basic-Programm-Endezeichen (drei Nullen) wird das Listen abgebrochen. Wird im Programm dann auch noch durch POKE 788,52 die RUN-STOP-, und durch POKE 792,193 die RESTORE-Taste ausgeschaltet, kann keiner mehr an das Programm. Aufheben läßt sich dieser List-Schutz nur mit einem Monitor und mit der Kenntnis der Funktionsweise des Schutzes.
(Thomas Uttendorfer)1 poke 2067,73:goto 10
2 rem"a{clr}{down}{down}{down}{yel}it is not allowed to list this program{blu}aa
1 POKE 2067,73:GOTO 10 2 REM "A{CLR,3DOWN,YELLOW}IT IS NOT ALLOWED TO LIST THIS PROGRAM{BLUE}AA
List- und Löschschutz leichtgemacht
Es wurden schon viele Methoden veröffentlicht, um ein Basic-Programm gegen Listen zu schützen. Aber alle mir bekannten Möglichkeiten weisen entschiedene Nachteile auf. Entweder der Schutz ist nicht sicher genug und leicht zu entfernen, oder er ist viel zu aufwendig.
Ich habe mich daher entschlossen, ein Programm zu schreiben, das diese Mängel umgeht und sogar noch andere positive Merkmale aufweist.
Zunächst eine Zusammenfassung von drei mir bekannten Listschutzmöglichkeiten mit ihren Vor- und Nachteilen:
1. Möglichkeit
In die erste Zeile des Basic-Programms (zum Beispiel Zeilennummer 1) wird REM, gefolgt von zwei Anführungszeichen und SHIFT L, geschrieben.
1 REM" "L (RETURN)
Der Cursor wird nun auf das zweite Anführungszeichen gesetzt und sechsmal SHIFT INST gedrückt (das Anführungszeichen wird um sechs Positionen nach rechts geschoben). Dann wird sechsmal DEL eingegeben (es erscheinen als Steuerzeichen sechs reverse T) und die Zeile mit (RETURN) abgespeichert. Wird nun der LIST-Befehl aufgerufen, meldet sich der Rechner mit:
"
?SYNTAX ERROR
READY.
Auf den ersten Blick sehr beeindruckend, aber durch Entfernen dieser Zeile ist der Listschutz wieder aufgehoben. Außerdem ist ein »LIST 2« noch möglich.
2. Möglichkeit
In jede Basic-Zeile werden synthetische Steuerzeichen eingefügt (genaue Beschreibung im 64'er-Magazin, Ausgabe 6/84). Diese Methode ist zwar recht sicher, will man aber alle Zeilen eines längeren Basic-Programms schützen, ist der Aufwand viel zu groß, vom Speicherplatzbedarf der Steuerzeichen ganz abgesehen.
3. Möglichkeit
Durch POKE 775,200 wird der Listbefehl außer Kraft gesetzt, durch POKE 775,167 wird diese Wirkung wieder aufgehoben. Dieser Listschutz ist zwar wirkungsvoll, aber er muß erst durch diesen POKE-Befehl aktiviert werden. Nach dem Laden eines Programms ist er daher noch nicht aktiv.
Das hier vorgestellte Programm erzeugt nicht nur einen sicheren Listschutz, sondern schützt auch vor dem Löschen einzelner Basic-Zeilen. So können zum Beispiel Hinweise auf ein Kopierrecht und auf den Autor eines Programms nicht geändert oder entfernt werden. Auch kann ein so gesichertes Programm nur mit RUN gestartet werden, ein RUN, gefolgt von einer Zeilennummer, führt zu einer Fehlermeldung. Jede Zeile des Programms ist geschützt, es können also auch einzelne Zeilen nicht gelistet werden. Einzige Bedingung für die Verwendung dieses Schutzes: Das zu schützende Programm darf keine Zeilennummern 0 und 1 enthalten. Ansonsten wird eine Fehlermeldung ausgegeben und das Programm bleibt unverändert.
Das Listschutzprogramm (Listing 6) liegt als Basic-Lader vor. Nachdem es richtig abgetippt wurde, kann es durch RUN gestartet werden. Das Maschinenprogramm steht dann im Speicher ab der Adresse 50000 zur Verfügung. Das zu schützende Basic-Programm kann nun geladen werden, durch SYS 50000 wird das Schutzprogramm aktiviert und das Basic-Programm geschützt. Es kann nun wieder auf Kassette/Diskette gespeichert werden. Das mit dem Listschutz versehene Programm ist nur um wenige Bytes größer als vorher.
Funktionsweise
Das Maschinenprogramm (Listing 6) generiert zwei Basic-Zeilen mit den Zeilennummern 0 und 1. Die Zeile 0 ist eine REM-Zeile, in der ein unlistbares Zeichen (SHIFT L) steht. Hinter diesem Zeichen stehen dann noch zwei kurze Maschinenprogramme, deren Funktionen im folgenden noch erklärt werden. In der zweiten Zeile steht ein SYS-Befehl, der eine der beiden Maschinenroutinen in Zeile 0 startet. Sind diese beiden Zeilen nun erzeugt, wird die Zeilennummer 0 durch eine höhere, eigentlich unerlaubte Zeilennummer (größer 64000) ersetzt. Diese Zeile kann daher auch nicht gelöscht werden.
Da alle nun folgenden Zeilen des Programms kleiner sind als die erste, können diese vom Computer nicht mehr erkannt werden. Ein Sprung in eine solche Zeile führt zu der Fehlermeldung: ?UNDEF'D STATEMENT ERROR. Es kann daher auch keine Zeile gelöscht werden, da diese für den Computer ja nicht mehr vorhanden sind.
Der einzige Nachteil ist, daß es nicht nur ein perfekter List- und Löschschutz, sondern auch ein RUN-Schutz ist (auch Sprungziele innerhalb des Programms können nicht gefunden werden).
Wird das geschützte Programm gestartet, trifft der Interpreter als erstes auf den SYS-Befehl in Zeile 1. Es folgt ein Sprung in das Maschinenprogramm in der REM-Zeile. Dort wird die Zeilennummer wieder auf 0 gesetzt, und der Vektor auf den Basic-Warmstart wird auf die zweite Maschinenroutine gesetzt.
Nun kann das Basic-Programm ohne Fehler ausgeführt werden. Wird der Programmlauf unterbrochen (durch STOP-Taste, Fehlermeldungen, Programmende und so weiter), wird das zweite Maschinenprogramm über den Basic-Warmstartvektor angesprungen. Dort wird die Zeilennummer wieder hochgesetzt, der Warmstartvektor wieder auf den normalen Wert gebracht und die Warmstartroutine angesprungen. Das Programm liegt nun wieder in der geschützten Form vor.
(Ulrich von Gaisberg)0 rem ********************************* 1 rem * (c) u. v. gaisberg * 2 rem * am zuckerberg 70 * 3 rem * 7140 ludwigsburg * 4 rem * tel. 07141/55910 * 5 rem ********************************* 6 fori=0to340:reada:b=b+a:poke50000+i,a 7 next i 8 if b <> 33527 then print"fehler in datas !":end 9 print"ok !":end 10 rem datas fuer maschinenprogramm 11 data169,0,141,32,208,141,33,208,169,1,141,134,2,32,68,229,174,3,8,172 12 data4,8,192,0,208,7,224,2,176,3,76,206,195,162,0,142,134,2,169,32,32 13 data210,255,232,224,50,208,246,162,0,189,21,196,157,0,4,232,224,29,208 14 data245,169,24,157,0,4,232,224,69,208,246,162,0,189,50,196,157,80,4,232 15 data224,8,208,245,162,0,189,58,196,157,120,4,232,224,8,208,245,162,10 16 data160,0,24,32,240,255,169,19,162,13,160,4,141,119,2,142,120,2,142,121 17 data2,142,122,2,132,198,96,162,0,189,99,196,32,210,255,232,224,31,208 18 data245,96,32,68,229,162,10,160,0,24,32,240,255,162,1,142,134,2,202,189 19 data66,196,32,210,255,232,224,33,208,245,169,20,162,17,160,255,141,18 20 data8,142,29,8,140,4,8,162,0,189,130,196,157,32,8,232,224,34,208,245 21 data96,48,18,5,13,34,148,148,148,148,148,148,148,148,148,148,34,12,12 22 data9,19,20,19,3,8,21,20,26,26,76,49,19,25,19,50,48,57,56,19,25,19,53 23 data48,49,52,48,80,82,79,71,82,65,77,77,32,45,32,40,67,41,32,85,46,86 24 data46,71,65,73,83,66,69,82,71,32,32,49,57,56,52,66,73,84,84,69,32,90 25 data69,73,76,69,32,48,32,85,78,68,32,49,32,69,78,84,70,69,82,78,69,78 26 data32,33,169,255,141,4,8,169,131,162,164,141,2,3,142,3,3,76,131,164 27 data165,2,141,4,8,169,32,162,8,141,2,3,142,3,3,96,0
Maschinenprogramme auf Tastendruck
Mit einer kleinen Routine kann man ein Maschinenprogramm mit einem Tastendruck aufrufen. Dafür benutzt man ein Zeichen, das normalerweise nicht oder nur selten verwendet wird. Ich habe mich für das @-Zeichen entschieden.
Im Interpreter existiert eine Schleife, die einen Basic-Befehl holt und ausführt.
A7E1 JMP (0308) ; zeigt normalerweise auf A7E4
A7E4 JSR 0073 ; nächstes Zeichen aus Basic-Text holen
A7E7 JSR A7ED ; Statement ausführen
A7EA JMP A7AE ; zurück zur Interpreterschleife
In den Speicherzellen $0308 und $0309 (776 und 777 dez) liegt ein Zeiger, der normalerweise auf den Beginn dieser Schleife zeigt. Verbiegt man nun den Zeiger auf eine eigene Routine, kann man den Basic-Befehl auf das eigene Zeichen überprüfen.
Wird es erkannt, springt man auf den Anfang des gewünschten Unterprogramms. Wurde das Zeichen nicht vorgefunden, macht man in der Schleife normal weiter.
Dieses Verfahren verwende ich bei der Programmierhilfe »Merge« aus Ausgabe 4/84, die normalerweise mit SYS 50000 gestartet werden muß. Es kann aber auch für andere Maschinenprogramme umgeschrieben werden.
»Merge« belegt den Speicherbereich 50000 bis 50264. Die eigene Routine beginnt auf Adresse 49152 (C000 hex). Der Wert in den Adressen $0308 und $0309 muß deshalb auf C000 abgeändert werden. Der Computer durchläuft dann vor jedem Befehl, den er ausführen soll, folgende Schleife:
C000 JSR 0073 ; nächstes Zeichen holen
C003 CMP 40 ; Vergleich mit @-Zeichen
C005 BEQ ; verzweigen wenn erkannt
C007 JSR 0079 ; Flags setzen
C00A JMP A7E7 ; Rücksprung
C00D JSR 0073 ; nächstes Zeichen holen
C010 JSR C350 ; zur eigenen Routine
C013 JMP A7AE ; Rücksprung
Nach dem Drücken von @ und RETURN wird nun das Programm ab Adresse 50000 (C350 Hex) ausgeführt. Auf die anderen Befehle hat diese Routine keinen Einfluß. Eine Hürde gibt es noch zu meistern. Die Änderung der Adressen 0308 und 0309 ist auf der Basic-Ebene mit POKE nicht möglich. Dies ist auch verständlich, da POKE auch ein Basic-Befehl ist und durch die Änderung der ersten Adresse der Einsprung verändert wird.
Deshalb muß diese Adreßänderung in Maschinensprache durchgeführt werden.
C100 LDA 00 ; Lade Akku mit 00
C102 STA 0308 ; Speichere Akku nach 0308
C105 LDA C0 ; Lade Akku mit C0
C107 STA 0309 ; Speichere Akku nach 0309
C10A RTS ; Rückkehr nach Basic
Basic-Lader für Befehlserweiterung
240 FOR I= 49152 TO 49152 + 21
250 READ Q : POKE I, Q
260 NEXT
300 FOR I = 49408 TO 49408 + 10
310 READ Q : POKE I, Q
320 NEXT : SYS 49408
11000 DATA 32,115,0,201,64,240,6,32,121
12000 DATA 0,76,231,167,32,115,0,32,80
13000 DATA 195,76,174,167
14000 DATA 169,0,141,8,3,169,192,141,9,3,96
Diesen Basic-Lader tippt man hinter das Programm »Merge« und speichert es gemeinsam ab.
Die Zeilennummern sind so gewählt, daß man sie direkt zum Basic-Lader von »Merge« dazutippen kann. In Zeile 10260 müssen aber dann die letzten fünf Nullen gelöscht werden.
Mit SYS 49408 wird die Befehlserweiterung aktiviert und steht dann zur Benutzung bereit.
(Patrik Fleig)Maschinenprogramme auf Diskette speichern
Reine Maschinenprogramme haben gegenüber einem Basic-Lader zwei entscheidende Vorteile. Sie sind wesentlich kürzer und können direkt, ohne zeitraubendes POKEn, geladen werden. Dieses Programm soll Ihnen helfen, Maschinenprogramme auf Diskette zu speichern.
Ein einfacher Basic-Lader besteht aus einer READ/POKE-Schleife, in der DATAs in den Speicher geschrieben werden. Jeder Wert, der in dieser Schleife gePOKEt wird, ist ein Byte eines Maschinenprogramms, ein Maschinenbefehl oder ein Teil davon. Anstatt die DATAs in den Speicher zu POKEn, kann ein Basic-Lader dazu benutzt werden, das Maschinenprogramm auf Diskette abzuspeichern. Der Lader wird dazu nur etwas geändert.
Ein Maschinenprogrammfile auf Diskette enthält, vor den Maschinenbefehlen, in den ersten beiden Bytes, die Startadresse des Programms. Der Computer erkennt daran, ab welcher Speicherstelle er das Programm laden soll.
Der Basic-Lader (Listing 7) muß also ein Programmfile eröffnen, die Startadresse des Maschinenprogramms ins File schreiben und anschließend alle Werte aus den DATA-Zeilen. Wie das im einzelnen programmiert wird, können Sie am Listing des Beispielprogramms sehen, das Sie ohne weiteres an jedes Ladeprogramm anpassen können.
Der wichtigste Befehl in diesem Beipiel steht in Zeile 50130:
OPEN 1,8,1, "Programmname"
Er öffnet eine Datei. Allerdings keine sequentielle, sondern eine Programmdatei. Die Sekundäradresse 1 sagt der Floppy 1541, daß nun ein Programm (NAME.PRG) geschrieben wird. Häufig findet man für diesen Befehl die Syntax
OPEN 2,8,2, "Programmname,P, W"
bei der man die Sekundäradresse frei wählen darf. Hier muß jedoch nach dem Namen angegeben werden, daß eine Programmdatei (P) geöffnet werden soll, in die geschrieben wird (Write). Entsprechend kann bei sequentiellen Dateien optional »S,W« bei Schreib- oder »S,R« bei Lesezugriffen angegeben werden.
Nachdem in Zeile 50130 die Programmdatei angelegt wurde, muß die Startadresse des Maschinenprogrammes gespeichert werden. Die Startadresse wird dazu in den Zeilen 50170 und 50180 in Low- und High-Byte zerlegt und die zwei Byte in Zeile 50190 in das Programmfile geschrieben. Jetzt wird das eigentliche Programm gespeichert. Die numerischen Werte müssen dazu mit der CHR$-Funktion in die entsprechenden Strings übersetzt werden. Um die erforderliche Datendichte beim Schreiben des Files zu erreichen, muß jedem String ein Semicolon »;« folgen. Ohne Semicolon ist das Programm später nicht lauffähig. Sind alle Werte, die der Basic-Lader in den Speicher gePOKEt hätte, gespeichert, wird die Datei mit CLOSE geschlossen. Damit ist das Maschinenprogramm auf Diskette gespeichert und kann mit
LOAD "NAME",8,1
geladen und, wenn dies notwendig ist, mit dem entsprechenden SYS-Befehl gestartet werden.
Laden von Maschinenprogrammen in Basic
Sie können Maschinenroutinen mit Hilfe von Basic-Programmen laden, ohne sie zu zerstören. Dabei ist zu beachten, daß nach dem Laden das Basic-Programm von neuem startet. Die Basic-Zeile
10 LOAD "KEIN ENDE",8,1
bewirkt deshalb eine Endlosschleife, die immer wieder das Maschinenprogramm »KEIN ENDE« lädt. Da angelegte Variablen dabei erhalten bleiben, kann mit
10 IF A=0 THEN A=1:LOAD "KEIN ENDE",8,1
ein mehrmaliges Laden verhindert werden, da beim Neustart A=1 ist.
(S. Wengler)50000 rem basic-lader 50010 data .................. 50020 data .................. 50030 data .................. 50040 : 50050 rem maschinenprogramme aus 50060 rem dataladern 50070 : 50080 rem s koennen weggelassen werden 50090 : 50100 rem da = startadresse 50110 rem ea = endadresse 50120 : 50130 open 1,8,1, "name" 50140 : 50150 rem sa u.ea zuordnen 50160 : 50170 sh = int(sa/256) :rem high-byte 50180 sl = sa-sh*256 :rem low-byte 50190 print#1,chrs$(sl);chr$(sh); 50200 : 50210 for i=sa to ea 50220 read wert 50230 print#1,chr$(wert); 50240 next i 50250 : 50260 close 1
50000 REM BASIC-LADER 50010 DATA .................. 50020 DATA .................. 50030 DATA .................. 50040 : 50050 REM MASCHINENPROGRAMME AUS 50060 REM DATALADERN 50070 : 50080 REM S KOENNEN WEGGELASSEN WERDEN 50090 : 50100 REM DA = STARTADRESSE 50110 REM EA = ENDADRESSE 50120 : 50130 OPEN 1,8,1, "NAME" 50140 : 50150 REM SA U.EA ZUORDNEN 50160 : 50170 SH = INT (SA/256) :REM HIGH-BYTE 50180 SL = SA-SH*256 :REM LOW-BYTE 50190 PRINT#1,CHRS$(SL);CHR$ (SH); 50200 : 50210 FOR I=SA TO EA 50220 READ WERT 50230 PRINT#1,CHR$ (WERT); 50240 NEXT I 50250 : 50260 CLOSE 1
Der C 64 als PET
Wenn Sie CBM 2000, 3000 oder 4000 geschriebene Programme auf Ihrem C 64 laufen lassen wollen, müssen Sie umständlich PEEKs und POKEs ändern. Der »Pet-Simulator« nimmt Ihnen diese Arbeit ab.
Ist das Programm (Listing 8) eingegeben und gestartet, werden als erstes die DATAs für das Maschinenprogramm in den Bereich ab Adresse 49152 gePOKEt (SU = Prüfsumme für die Daten). Danach fragt das Programm nach der Zeichenfarbe. Sie werden aufgefordert, eine Zahl zwischen 0 und 15 einzugeben.
(0 = schwarz 1 = weiß,..., 15 = grau 3).
Bei anschließendem Starten des Maschinenprogrammes wird das Basic-ROM in das darunterliegende RAM gePOKEt (Basic-Interpreter kopieren). Anschließend wird das Bildschirm-RAM von Adresse 1024 nach Adresse 32768 verlegt. Basic-Speicheranfang und -ende werden dem des PET angepaßt. Weiterhin wird in der POKE-Routine des Basic-Interpreters ein Eingriff vorgenommen, nach der der Computer aus dem Interpreter in eine Routine des Maschinenprogramms springt. Hier wird überprüft, ob das Bildschirm-RAM angesprochen wurde. Trifft dies zu, wird die dazugehörige Farb-RAM-Adresse berechnet und der vorher festgelegte Farbwert (Zeichenfarbe) hineingePOKEt. Um das Zurücksetzen des Bildschirmes auf das C 64-Format zu vermeiden (durch Drücken der RUN/STOP- und RESTORE-Tasten), wird die RESTORE-Taste durch Verändern des NMI-Vektors ausgeschaltet. Programme können aber noch mit der RUN/STOP-Taste unterbrochen werden.
Nach Ablauf des Maschinenprogrammes meldet sich der Computer mit »PET-SIMULATOR AKTIV«. Sie können jetzt immer noch die Zeichenfarbe mit POKE 49239, ZF (ZF = Zeichenfarbe – siehe oben) ändern. Wenn Sie jetzt zum Beispiel POKE 32768,1 eingeben, erscheint ein »A« am linken oberen Bildschirmrand in der gewählten Zeichenfarbe. Schlußbemerkung: Bevor Sie das Programm starten, empfiehlt es sich, es vorher zu speichern, da sich das Programm selbständig löscht.
(Wolfgang Hopf)1 rem *********************************
2 rem * pet - simulator *
3 rem * *
4 rem * (c) by w. hopf 1984 *
5 rem *********************************
6 :
7 rem programm vor dem start abspeichern
8 :
10 fori=49152to49152+91:reada:su=su+a
20 pokei,a:next
30 ifsu<>12552thenend
40 print"{clr}{down}{down}bitte waehlen sie die zeichenfarbe"
50 print"{down}(0-15 eingeben)!{down}"
60 inputzf:ifzf>=0andzf<=15thenpoke49239,zf:poke646,zf:goto80
70 print"{down}nicht erlaubt":fori=1to1000:next:goto40
80 sys49152:poke1,54:print"{clr}pet-simulator aktiv":new
10000 data160,0,132,254,169,160,133,255
10005 data177,254,145,254,200,208,249,230
10010 data255,166,255,224,192,208,241
10015 data169,5,141,0,221,141,24,208,169
10020 data128,141,136,2,133,56,169,4
10025 data133,44,169,0,141,0,4,169
10030 data63,141,37,184,169,192,141,38
10035 data184,169,193,141,24,3,96,32
10040 data235,183,24,165,21,201,128,144
10045 data18,201,132,176,14,24,105,88
10050 data133,255,165,20,133,254,169,0
10055 data234,145,254,96
60000 :
60010 rem liste der verwendeten commodore-steuerzeichen
60020 rem "{clr}" = clr
60030 rem "{down}" = crsr-down
Pseudo-Interrupt
Diese Befehlserweiterung erlaubt es, ein Basic-Programm zu jedem beliebigen Zeitpunkt per Tastendruck durch die F1-Taste unterbrechen zu lassen. Es kann dann in eine vorher definierte Basic-Routine gesprungen werden. Diese könnte zum Beispiel den noch freien Speicherplatz oder die Uhrzeit anzeigen.
Das Programm (Listing 9) bitte mit dem MSE eingeben. Es liegt dann im Speicherbereich von 40499 bis 40768. Geladen wird es absolut mit LOAD "PSEUDO-IRQ",8,1. Da das Programm im Bereich für die Basic-Variablen steht, muß es durch POKE 56,158:CLR vor Überschreiben geschützt werden. Nach dem Start durch »SYS 40541« stehen die neuen Befehle zur Verfügung:
!F1JUMP <Zeilennummer> legt fest, in welche Zeile im Falle einer Unterbrechung durch die F1-Taste gesprungen werden soll. Tritt der Befehl mehrmals auf, so gilt die zuletzt angegebene Zeilennummer.
!JBACK bewirkt die Fortsetzung des Basic-Programms ab der Stelle, an der unterbrochen wurde.
!SF1 verhindert Unterbrechungen. Dies kann zum Beispiel beim Aufbau einer Grafik oder bei Arbeiten mit der Diskettenstation wichtig sein.
!CF1 läßt gesperrte Unterbrechungen wieder zu.
(Guido Schuhmacher)PROGRAMM : PSEUDO-IRQ 9E01 9F41 ----------------------------------- 9E01 : FF 89 00 20 73 00 C9 21 6A 9E09 : D0 03 4C 6D 9E A5 CB C9 F5 9E11 : 40 D0 06 20 79 00 4C E7 D8 9E19 : A7 C9 04 F0 06 20 79 00 0B 9E21 : 4C E7 A7 A5 CB C9 40 D0 AD 9E29 : FA AD 01 9E F0 06 20 79 C1 9E31 : 00 4C E7 A7 18 A9 03 20 61 9E39 : FB A3 A5 7A 48 A5 7B 48 EF 9E41 : A5 39 48 A5 3A 48 A9 75 C1 9E49 : 48 8D 01 9E AD 02 9E 85 DC 9E51 : 14 AD 03 9E 85 15 20 A3 99 9E59 : A8 4C AE A7 A9 04 8D 08 C9 9E61 : 03 A9 9E 8D 09 03 A9 75 CC 9E69 : 8D 01 9E 60 20 73 00 C9 5C 9E71 : 46 F0 07 C9 4A F0 41 4C F4 9E79 : F1 9E 20 73 00 C9 31 D0 E5 9E81 : 34 20 73 00 C9 4A D0 2D 2F 9E89 : 20 73 00 C9 55 D0 26 20 51 9E91 : 73 00 C9 4D D0 1F 20 73 8E 9E99 : 00 C9 50 D0 18 20 73 00 FC 9EA1 : 20 6B A9 A5 14 8D 02 9E 89 9EA9 : A5 15 8D 03 9E A9 00 8D EF 9EB1 : 01 9E 4C AE A7 4C 08 AF 47 9EB9 : 20 73 00 C9 42 D0 F6 20 93 9EC1 : 73 00 C9 41 D0 EF 20 73 C3 9EC9 : 00 C9 43 D0 E8 20 73 00 F6 9ED1 : C9 4B D0 E1 68 C9 75 D0 FC 9ED9 : 59 68 85 3A 68 85 39 68 77 9EE1 : 85 7B 68 85 7A A9 00 8D FF 9EE9 : 01 9E 20 79 00 4C E7 A7 C2 9EF1 : C9 53 F0 07 C9 43 F0 1C 34 9EF9 : 4C 08 AF 20 73 00 C9 46 24 9F01 : D0 B3 20 73 00 C9 31 D0 D6 9F09 : AC A9 75 8D 01 9E 20 73 05 9F11 : 00 4C AE A7 20 73 00 C9 09 9F19 : 46 D0 9A 20 73 00 C9 31 33 9F21 : D0 93 A9 00 8D 01 9E 20 C1 9F29 : 73 00 4C AE A7 4A 42 41 DE 9F31 : 43 CB A9 2E 85 22 A9 9F D9 9F39 : 85 23 4C 47 A4 01 00 A5 E9
Es muß nicht immer »READY.« sein...
Wenn Sie sich darüber ärgern, daß der C 64 nach jedem ausgeführten Befehl sein stupides »READY.« auf den Bildschirm schreibt, dann geben Sie doch die beiden folgenden Zeilen im Direktmodus ein:
FOR I=40960 TO 49151 : POKE I,PEEK(I) : NEXT : POKE 1,54 : REM Basic-Interpreter ins RAM laden
FOR I= 41848 TO 41853 : POKE I,32 : NEXT : REM READY-Meldung überschreiben
Wenn Sie jetzt irgendeinen Befehl eingeben, erscheint kein »READY.« mehr. Natürlich können Sie aber auch einfach den Text ändern:
A$="HALLO." : FOR I=1 TO 6 : POKE 41847+I,ASC(MID$(A$,I,1)) : NEXT
Nach Eingabe dieser Zeile meldet sich der Interpreter nach jeder Eingabe mit »Hallo.«. Sie können jeden beliebigen Text wählen, vorausgesetzt, er ist maximal sechs Zeichen lang.
(Andreas Scharrer)Reset
Falls Sie in einem Programm einen Reset wünschen, dann benutzen Sie folgenden Befehl:
SYS 64738
Mit folgendem kleinen Programm sorgt man von Basic aus dafür, daß ein Reset keinen Effekt hat:
100 FOR I=32770 TO 32778
110 READ A : POKE I,A
120 NEXT I
130 DATA 10, 128, 195, 194, 205
140 DATA 56, 48, 88, 0
(Daniel Kossmann)
Einfacher Reset-Schalter selbstgebaut
Sehr preiswert und einfach kommt man im Selbstbau zu einem Reset-Schalter, wenn man sich im Elektronikfachgeschäft einen sechspoligen Diodenstecker und einen Miniatur-Tastschalter besorgt. Der Tastschalter wird zwischen die Pins 2 und 6 des Diodensteckers gelötet. Zur Pinbelegung vergleiche auch Seite 142 im C 64-Handbuch. Der so präparierte Diodenstecker wird nun in den seriellen Port des C 64 beziehungsweise VC 20 gesteckt. Falls der Port bereits von Floppy oder Drucker belegt ist, kann der Stecker natürlich auch in die freie Buchse des entsprechenden Zusatzgerätes eingesteckt werden. Auf Knopfdruck wird nun in jedem Fall wieder der Einschaltzustand des Computers hergestellt.
Die Kosten für Stecker und Taste betragen etwa 4 Mark.
(Henning Zipf)Reset-Helfer für C 64
Das Betriebssystem des C 64 enthält ab der Adresse $FD02 ein Unterprogramm, das im Steckmodulbereich ab $8000 nach der Zeichenfolge »CBM80« sucht. Nach dem Einschalten des Computers oder nach einem Reset wird dieses Unterprogramm jedesmal aufgerufen. Werden ab der Adresse $8003 die Zeichen »CBM80« gefunden, dann wird nicht zum Basic-Start gesprungen, sondern das Betriebssystem nimmt an, daß ein Modul eingesteckt ist, holt sich aus der Speicherzelle $8000/$8001 die Startadresse des Modulprogramms und verzweigt dorthin.
Das kleine »Reset-Helfer«-Programm (Listing 10) nutzt dies aus, indem es die genannten Speicherstellen in geeigneter Weise abändert. Es schreibt die »CBM80«-Zeichenfolge ab $8003 in RAM und läßt die Speicherstellen $8000/$8001 auf den Basic-Warmstart zeigen.
Wenn man jetzt einen Reset auslöst, kommt man wie gewohnt aus allen »abgestürzten« Programmen heraus, ein vorhandenes Basic-Programm bleibt aber erhalten.
(Henning Zipf)100 rem *** reset-helfer *** 110 rem 120 rem henning zipf 130 rem kirchstr. 8 140 rem 6086 riedstadt 5 150 rem tel. (06158) 72453 160 rem 170 for i=1 to 9 180 read d 190 poke 32767+1,d 200 next i 210 poke53280,14:poke53281,6 220 printchr$(147);chr$(5) 230 print" c 64 changed reset vektor" 240 print 250 print" 64 k ram system 38911 basic bytes free" 260 print 270 new 280 data 0,0,255,0,195,194,205,56,48 290 rem erst save, dann run !
RESTORE für Unterprogramme
Will man in ein Programm ein schon vorhandenes Unterprogramm einfügen, kann es beim Lesen von DATAs Schwierigkeiten geben. Oft genügt die RESTORE-Anweisung nicht.
Wenn beide Programmteile, Hauptprogramm und Unterprogramme, DATAs enthalten, muß sichergestellt werden, daß auch wirklich die richtigen Werte gelesen werden. Wenn man nicht aufpaßt, kann es passieren, daß das Unterprogramm DATAs aus dem Hauptprogramm liest. Wie kann man das verhindern? Es gibt eine umständliche Methode: Man kann eine kleine Basic-Erweiterung einbauen, den RESTORE X-Befehl. Es geht aber auch einfacher. Die Zeropage, das sind die ersten 256 Bytes des Speichers, hilft uns bei der Lösung des Problems. Genauer gesagt, die Adressen 65/66 und 122/123. Schlagen wir im C 64-Handbuch auf Seite 162 nach, dann steht dort:
65- 66 Adresse des aktuellen DATA-Elements
122-123 Basic-Zeiger innerhalb der Subroutine
Mit diesen Informationen läßt sich schon etwas anfangen. Wenn das Unterprogramm angesprungen wird, dann sollte der Zeiger in Speicherstelle 122/123 auf die Adresse des Unterprogramms im Speicher stehen. POKEt man diese Werte in die Zeilen 65/55 mit
POKE 65,PEEK(122)
POKE 66,PEEK(123),
so wird beim nächsten READ der Wert gelesen, der hinter dieser Basic-Zeile mit den POKEs steht, also das erste DATA-Element innerhalb des Unterprogramms. Nach dem Rücksprung aus dem Unterprogramm muß der Zeiger eventuell auch im Hauptprogramm wieder gestellt werden.
In dem kurzen Demo-Listing (Listing 11) werden drei Unterprogramme in zufälliger Reihenfolge aufgerufen.
(Stephan Pätzold)1 rem ************************
2 rem * demo *
3 rem * subroutine-restore *
4 rem ************************
5 print"{clr} taste druecken !"
6 print:print
10 x=int(rnd(ti)*3)+1
20 on x gosub 1000,2000,3000
25 poke 65,peek(122):poke 66,peek(123)
30 read a$:print a$
50 data " hauptprg."
100 goto 10
1000 rem *** subroutine 1 ***
1005 :
1010 poke 65,peek(122):poke 66,peek(123)
1020 for i=1 to 4:read a:print a;:next
1030 read a$:print a$;
1040 poke 198,0:wait 198,1
1050 data 1,11,111,1111,"up1 "
1060 return
1070 :
2000 rem *** subroutine 2 ***
2005 :
2010 poke 65,peek(122):poke 66,peek(123)
2020 for i=1 to 4:read a:print a;:next
2030 read a$:print a$;
2040 poke 198,0:wait 198,1
2050 data 2,22,222,2222,"up 2 "
2060 return
2070 :
3000 rem *** subroutine 3 ***
3005 :
3010 poke 65,peek(122):poke 66,peek(123)
3020 for i=1 to 4:read a:print a;:next
3030 read a$:print a$;
3040 poke 198,0:wait 198,1
3050 data 3,33,333,3333,"up 3"
3060 return
3070 :
1 REM ************************ 2 REM * DEMO * 3 REM * SUBROUTINE-RESTORE * 4 REM ************************ 5 PRINT"{CLR,6SPACE}TASTE DRUECKEN !" 6 PRINT:PRINT 10 X=INT (RND (TI)*3)+1 20 ON X GOSUB 1000,2000,3000 25 POKE 65,PEEK (122):POKE 66,PEEK (123) 30 READ A$:PRINT A$ 50 DATA " HAUPTPRG." 100 GOTO 10 1000 REM *** SUBROUTINE 1 *** 1005 : 1010 POKE 65,PEEK (122):POKE 66,PEEK (123) 1020 FOR I=1 TO 4:READ A:PRINT A;:NEXT 1030 READ A$:PRINT A$; 1040 POKE 198,0:WAIT 198,1 1050 DATA 1,11,111,1111,"UP1{2SPACE}" 1060 RETURN 1070 : 2000 REM *** SUBROUTINE 2 *** 2005 : 2010 POKE 65,PEEK (122):POKE 66,PEEK (123) 2020 FOR I=1 TO 4:READ A:PRINT A;:NEXT 2030 READ A$:PRINT A$; 2040 POKE 198,0:WAIT 198,1 2050 DATA 2,22,222,2222,"UP 2 " 2060 RETURN 2070 : 3000 REM *** SUBROUTINE 3 *** 3005 : 3010 POKE 65,PEEK (122):POKE 66,PEEK (123) 3020 FOR I=1 TO 4:READ A:PRINT A;:NEXT 3030 READ A$:PRINT A$; 3040 POKE 198,0:WAIT 198,1 3050 DATA 3,33,333,3333,"UP{2SPACE}3" 3060 RETURN 3070 :
RAM-Floppy
Wer kennt das nicht: ein paar Veränderungen an einem Programm – eine Zeile rein, eine andere raus – und nichts geht mehr. Das lästige Neuladen des Originalprogramms von Diskette können Sie ab jetzt vergessen.
Ist ein Programm mal wieder zu Tode editiert, werden Sie nun nicht mehr von den langen Ladezeiten der 1541 in Ihrem Programmierdrang gebremst. Mit »RAM-Floppy« (Listing 12) kann ein Programm bearbeitet werden, während man eine Kopie davon im RAM hat. In Sekundenschnelle kann die Kopie in den Basic-Speicher gebracht oder mit der Orginalversion vertauscht werden. Ganz einfach durch Eingabe von »@V« oder »@T«. Numerische Variablen bleiben dabei erhalten. Die »RAM-Floppy« besitzt eine Speicherkapazität von maximal 25 KByte. Der Speicher beginnt ab Adresse 40960.
Ein Problem ergibt sich im Speicherbereich des Kernal- und Basic-ROMs. Ein POKE-Befehl schreibt ins RAM, während die PEEK-Funktion auf das ROM zugreift. Noch komplizierter sieht es beim Zeichen-ROM und den I/O-Bausteinen aus. Wie Sie vielleicht aus unserem Grafikkurs wissen, gibt es in diesen Bereichen drei Speicheretagen. Der Inhalt der Zelle 1 regelt den Zugriff des Computers auf die verschiedenen Speicherebenen. Werden die Bits 0 und 1 in Adresse 1 gelöscht, sieht der Computer nur noch das RAM. Basic- und Kernel-ROM sind verschwunden. Löschen Sie diese Bits deshalb nur durch ein Maschinenspracheprogramm, wenn vorher Ein- und Ausgaben gesperrt wurden. Dies wird durch Setzen des Interruptregisters erreicht.
Das Maschinenprogramm besteht aus drei Teilen. Im Bereich von 40704 bis 40768 erfolgt die Auswertung der Befehle von »RAM-Floppy« und der Aufruf der beiden Unterprogramme, die das Tauschen oder Verschieben der Basic-Programme erledigen.
Das abgedruckte Basic-Programm (Listing 12) POKEt das Maschinenprogramm ab Adresse 40704. Mit SYS 40704 wird es initialisiert.
Die »RAM-Floppy« hat eine Kapazität von 25 KByte. Das Programm im Basic-Speicher kann zwar 38 KByte lang sein, läßt sich dann allerdings nicht mehr vollständig verschieben oder vertauschen. Der Speicherbedarf sollte auch bei Programmen mit vielen Variablen nicht außer acht gelassen werden. Bei langen Programmen mit vielen Variablen kann es durchaus vorkommen, daß die Programme zwar getauscht, die Variablen allerdings nicht mehr übernommen werden können.
(Uwe Klatt)0 rem**********************************
1 rem* ram-floppy *
2 rem**********************************
3 rem* uwe klatt *
4 rem* billerbecker str. 27 *
5 rem* 4939 steinheim *
6 rem* tel. 05233/5672 *
7 rem**********************************
8 poke53280,0:poke53281,11
9 poke646,8
10 print"bitte warten"
11 rem *****************************
12 rem *** datas lesen ***
13 rem *****************************
14 fori=40704to40768:reada:pokei,a:s=s+a:next
15 ifs<>6567thenend
16 fori=40784to40849:reada:pokei,a:s=s+a:next
17 ifs<>14392thenend
18 fori=40853to40902:reada:pokei,a:s=s+a:next
19 ifs<>20412thenend
20 rem *****************************
21 rem *** menue ***
22 rem *****************************
23 printchr$(147)
24 print"{rvon} ";
25 print"{rvon} ram-floppy 25.5 kbyte ";
26 print"{rvon} "
27 print"'@v' verschiebt programm in ram-floppy"
28 print"'@t' vertauscht programm mit ram-floppy"
29 rem *****************************
30 rem *** mc programm starten ***
31 rem *****************************
32 sys40704:new
33 rem *****************************
34 rem *** datas fuer 1. mc teil ***
35 rem *****************************
36 data169,159,133,56,133,52,169,0,133,55,169,21,141,8,3,169
37 data159,141,9,3,96,32,115,0,240,4,201,64,240,3,76,231
38 data167,32,115,0,201,84,240,7,201,86,240,12,76,8,175,32
39 data115,0,32,80,159,76,174,167,32,115,0,32,149,159,76,174
40 data167
41 rem *****************************
42 rem *** datas fuer 2. mc teil ***
43 rem *****************************
44 data169,0,133,45,169,104,133,46,120,165,1,41,252,133,1,169
45 data0,133,98,133,100,141,0,160,169,160,133,101,169,8,133,99
46 data162,96,160,0,177,98,133,102,177,100,145,98,165,102,145,100
47 data200,208,241,230,99,230,101,202,208,232,165,1,9,3,133,1
48 data88,96
49 rem *****************************
50 rem *** datas fuer 3. mc teil ***
51 rem *****************************
52 data120,165,1,41,252,133,1,169,0,133,98,133,100,141,0,160
53 data169,160,133,101,169,8,133,99,162,96,160,0,177,98,145,100
54 data200,208,249,230,99,230,101,202,208,240,165,1,9,3,133,1
55 data88,96
Sequentielle Datei als Basic-Programm laden
Es sind eine Reihe von Anwendungen denkbar, bei denen aus einer sequentiellen Datei auf Diskette oder Kassette ein lauffähiges Basic-Programm erstellt werden soll (Datenfernübertragung, Umwandlung von Textfiles in Basic-Programme). Der folgende Einzeiler macht's für den VC 20 möglich:
OPEN 1, (Gerät), (Sekundäradresse), "(Name)" :
POKE 812, 238 : POKE 781, 1 : SYS 65478
Dieses Miniprogramm öffnet das File Nummer 1 als Eingabefile (anstelle der Tastatur). Außerdem wird der CLALL-Vektor des Betriebssystems auf ein »RTS« gesetzt, so daß beim Einlesen von Programmzeilen keine Files geschlossen werden.
Deshalb werden nach Eingabe der obigen Befehlszeile von der ausgewählten Datei so lange Zeilen eingelesen und anschließend sofort im Direktmodus ausgeführt, bis die Betriebssystem-Routine CLRCHN aufgerufen wird (zum Beispiel durch einen Syntaxfehler in den gelesenen Zeilen oder durch GET #1, A$).
Um in den normalen Eingabemodus zurückzukehren, muß nur »POKE 812, 239 : CLR« eingegeben werden.
Zum Ausprobieren: Laden Sie ein beliebiges Basic-Programm und geben Sie danach im Direktmodus ein:
OPEN 1,8,3,"LISTING,S,W": CMD 1 : LIST : PRINT#1 :
CLOSE 1
Spezialeffekt
Wenn man beim C 64 in die Speicherstelle 53270 Werte zwischen 0 und 15 schreibt (POKE 53270,x), kann man den Bildschirm um bis zu sieben Bildpunkte nach links oder rechts scrollen lassen. Ist x kleiner als 8, dann scrollt der Bildschirmausschnitt um x Bildpunkte nach links, sonst um x-8 Bildpunkte nach rechts.
POKE 53270,8 stellt den Normalzustand wieder her. Dieser Trick läßt sich gut bei Action-Spielen als optische Untermalung beispielsweise einer Explosion einsetzen.
(Michael Keukert)Text und Grafik mischen
Im Leserforum des 64'er-Magazins, Ausgabe 8/84, fragte Frank Schager nach einer Möglichkeit, mit Simons Basic ein Textfenster in der hochauflösenden Grafik zu erzeugen.
Mit dem folgenden kleinen Programm wird die normale Tastaturabfrage mit dem Simons Basic-Befehl »TEXT« verbunden:
10 X = 2 : Y = 2 : REM Text-Anfang
20 HIRES 15, 11 : REM Grafik ein
30 GET A$
40 IF A$ < > " " THEN GOSUB 100
50 GOTO 30
60 REM
100 X = X + 8 : REM X-Koordinate erhöhen
110 IF X >38 * 8 THEN X = 2 : Y = Y + 8 : REM Zeilenende? Dann neue Zeile
120 TEXT X,Y,A$,1,1,8 : REM Zeichen drucken
130 AA$ = AA$ + A$ : REM Wort erzeugen
140 IF AA$ = "GEHE" THEN 1000 : REM Zum Beispiel
150 RETURN
Veränderbar ist auch der Faktor 38 in Zeile 110, je nachdem, welche Zeilenlänge gewünscht wird. Ebenso besteht die Möglichkeit, zwischen den Zeilen 130 und 150 weitere IF-Abfragen einzubauen. Empfehlenswert ist die besondere Abfrage der Tasten SPACE und RETURN.
(Jörg Prante)VC 20-Grundversion simuliert
Mit der folgenden kurzen Routine lassen sich die meisten Grundversions- oder +3 KByte-Programme auch mit einer 8 KByte-Erweiterung laden und ausführen:
POKE 648, 30 : SYS 64821
POKE 4096, 0 : POKE 44, 16 : NEW
Da der Bildschirmspeicher durch die kleine Routine an der gleichen Stelle wie in der Grundversion liegt, sind die meisten Grundversions-Programme direkt lauffähig.
Automatische Zeilennumerierung
Das lästige Durchnumerieren der Zeilen bei der Programmierung kann Ihnen dieses kleine Programm abnehmen.
Die Syntax des AUTO-Befehls ist:
←A anfangszeilennummer, schrittweite
Nach Eingabe dieses Befehls wird die Zeilennummer vorgegeben und nach RETURN um »schrittweite« erhöht.
Um aus dem AUTO-Modus wieder herauszukommen, muß man nach Vorgabe einer Zeilennummer
»←« RETURN eingeben.
Falls man nach Vorgabe einer Zeilennummer die RETURN-Taste betätigt, wird die entsprechende Zeile, falls sie vorhanden ist, gelöscht. Hiermit lassen sich auch sehr schnell Programmblöcke löschen, falls man die RETURN-Taste gedrückt hält, die Zeilenvorgabe weiterläuft und die entsprechenden Zeilennummern gelöscht werden.
»←«=CHR$(95)
»A«=CHR$(65)
Das Programm (Listing 13) als Basic-Lader eintippen, anschließend mit RUN starten. Falls »FEHLER IN DEN DATA-ZEILEN« erscheint, DATAs auf Tippfehler überprüfen. Falls »OK«, kann die Basic-Erweiterung mit SYS 49152 initialisiert werden. Nun hat man das Basic um den Befehl »A« erweitert.
(Frank Siedel)1010 rem******************************* 1020 rem** auto fuer c 64 ** 1030 rem** von ** 1040 rem** frank siedel ** 1050 rem** posener str. 18 ** 1060 rem** 2945 sande ** 1070 rem******************************* 1080 : 1090 : 1100 : 1110 :data169,11,141,8,3,169,192,141,9,3,96,32,115,0,8,201,95,240,4,40,76,231 1120 :data167,32,115,0,201,65,208,245,32,115,0,24,32,107,169,165,20,133,38 1130 :data165,21,133,39,32,253,174,24,32,107,169,165,20,133,40,165,21,133,41 1140 :data169,129,141,2,3,169,192,141,3,3,169,128,141,138,2,165,39,133,98,165 1150 :data38,133,99,162,144,56,32,73,188,32,221,189,162,0,189,1,1,240,9,157 1160 :data0,2,32,210,255,232,208,242,32,18,225,201,95,240,30,201,13,240,45 1170 :data157,0,2,232,32,98,165,76,134,164,24,165,38,101,40,133,38,165,39,101 1180 :data41,133,39,76,75,192,169,131,141,2,3,169,164,141,3,3,169,0,141,138 1190 :data2,40,76,116,164,32,118,165,76,134,164 1200 : 1210 : 1220 printchr$(147) 1230 su=0 1240 fori=1to170 1250 reada 1260 su=su+a 1270 poke49151+i,a 1280 next 1290 ifsu<>17417 then print "fehler in den datazeilen":end 1300 print"ok":end
Zwei Tips für den C 64
Die Speicherstellen 57 und 58 enthalten die Zeilennummer der aktuellen Basic-Zeile. Die Abfrage geschieht mit »PRINT PEEK(57) + 256 * PEEK(58)«.
Mit »PRINT PEEK(1)« kann abgefragt werden, ob eine Taste an der Datasette gedrückt ist. Es gibt drei mögliche Werte:
7: Taste gedrückt,
55: keine Taste gedrückt,
39: Taste gedrückt, aber Programmlauf unterbrochen.
Diese Abfragen sind für die benutzerfreundliche Programmierung von Kassettenoperationen recht nützlich.
(Wolfgang Meyer/kn)Und noch ein Tip
Der FORMULAR TOO COMPLEX-Error ist sehr unangenehm, da sich das Programm danach oft nicht mehr listen läßt. Nach Eingabe von POKE 24,0 verhält sich der Computer aber wieder normal.
(Roger Limberg)