C 64
Tips & Tricks

Tips & Tricks für Profis

Neben Beiträgen über Listschutz bringen wir zwei erstaunliche Programme, die den Rasterzeilen-Interrupt ausnutzen. Weiterhin eine Joystick-Bastelei und ein Programm zur Zahleneingabe mit dem Joystick.

Gibt es den perfekten Listschutz? Sicherlich nicht. Das Programm »H.I.D.E.« von Frank Hund (siehe weiter unten) stellt die zur Zeit wohl beste Lösung dar. Aber gibt es noch bessere Möglichkeiten? Wo liegen die Grenzen eines Listschutzes (ohne Autostart)? Hat der Basic-Interpreter außer der <SHIFT+L>-Macke noch andere Programmierfehler? Kennen Sie als ausgefuchster C 64-Profi noch eine andere Methode? Wenn ja, schicken Sie uns diese! Der beste Profi-Listschutz wird unter Tips & Tricks veröffentlicht.

(tr)

Fehler im LIST-Befehl

Wie Sie sicher wissen, ist folgende Programmzeile gegen den LIST-Befehl insofern geschützt, als beim Listen dieser Zeile anstelle des geSHIFTeten L ein »SYNTAX ERROR« auftritt.

10 REM <SHIFT+L>

Dieser Listschutz ist einer der einfachsten und hat entsprechend oft — vor allem bei Einsteigern — Verwendung gefunden. Um ein auf diese Weise geschütztes Programm problemlos listen zu können, ist folgender Einzeiler (Befehlsabkürzungen verwenden, Leerzeichen nicht eintippen) vor dem Listen einzugeben:

POKE 95,0:POKE 96, 160:POKE 90,0:POKE 91,192:POKE 88,0:POKE 89,192:SYS 41919: POKE 1,54:POKE 42816, 144

Dann erscheint statt der »SYNTAX ERROR«-Meldung der Basic-Befehl END. Als Profis wollen wir uns aber nicht damit zufriedengeben, den Listschutz zu umgehen (wofür das Programm »LIST-KNACKER — Und er LISTet doch!« aus dem 64'er-Sonderheft 2/86 »Tips & Tricks« viel besser geeignet ist), sondern vor allem klären, warum dieser Listschutz funktioniert und wie er behoben wird.

Verantwortlich ist ein kleiner Fehler in der LIST-Routine, den wir mit Hilfe des SMON genau aufzeigen wollen. Mit »M A09E A19E« können Sie die Tabelle der Befehlswörter, welche der Computer zur Decodierung der Tokens in Klartext einsetzt, ausgeben lassen, mit »D A717 A741« die Umwandlungsroutine, der das Token im Akkumulator übergeben wird. Zunächst wird aus dem Token ermittelt, ab welcher Position in der Tabelle ab $A09E das benötigte Befehlswort steht. Betrachten wir nun das Bild 1, eine Hardcopy von einem Bildschirm, auf dem die verantwortlichen Teile des ROMs stehen.

Bildschirmausdruck eines Maschinensprachemonitors mit einer Hexdump-Tabelle und einem Disassembler-Listing
Diese Teile des Basic-Interpreters sind für den Fehler verantwortlich

Bei $A738 wird dann Zeichen für Zeichen das Befehlswort ausgegeben, da dort die Position in der Tabelle bereits im Y-Register steht. Wie man am Hex-Dump der Befehlswörter-Tabelle sieht, ist im letzten Zeichen eines Kommandos Bit 7 gesetzt. Diese Endmarkierung wird von $A73B erkannt, andernfalls wird das Zeichen bei $A73D ausgegeben. Nun kommt die kritische Stelle. Normalerweise ist das auszugebende Zeichen nicht CHR$(0) und somit das Z-Flag nach Ausgabe des Zeichens gelöscht, wodurch der BNE-Befehl bei $A740 einem JMP gleichkommt (mehr über diesen und andere Programmiertricks in »Effektives Programmieren in Assembler«, 64'er-Assembler-Sonderheft 8/85, Seite 74).

Bei $CC, dem Code, der durch das geSHIFTete L erzeugt wird, gibt es allerdings eine Ausnahme: nach der Umwandlung des Tokens in den Offset steht in der Tabelle bei $A738 im YRegister der Wert $FF (dies können Sie mit dem Trace-Befehl des SMON nachvollziehen, indem Sie in den Akku den Wert $CC schreiben, von $A717 bis $A738 TRACEn lassen und dabei den Wert des Y-Registers beobachten), wodurch der Inhalt von $A19D ausgelesen wird. Wie das Hex-Dump zeigt (siehe Bild), steht dort ein Null-Byte!

Die Folgen ergeben sich ganz logisch: bei $A740 ist das Z-Flag gesetzt, da der Akku den Wert 0 hatte, und es erfolgt keine Verzweigung, was aber zur fehlerfreien Funktion unbedingt notwendig wäre. Statt dessen wird die im Speicher direkt hinter der »LIST«-Routine liegende »FOR«-Routine abgearbeitet (ab $A742), die ihrerseits die Parameter des »FOR«-Befehls einzuholen versucht (bei $A746 wird der»LET«-Befehl zur Definition der Schleifenvariablen aufgerufen). Da wir aber nach »LIST« keine »FOR«-Parameter eingeben können, vermißt der Interpreter solche: SYNTAX ERROR!

Nun wissen wir, wie es zu dieser Fehlermeldung kommt, die einen Abbruch des Listens bewirkt. Mit Hilfe des SMON fanden wir heraus, wie man diese Genauigkeit der LIST Routine behebt. Wenn das Interpreter-ROM in das an gleicher Adresse liegende RAM kopiert wird, kann man den BNE-Befehl bei $A740 in einen »BCC« umwandeln. Dieser Verzweigungsbefehl funktioniert einwandfrei, da bei der Bildschirmausgabe ($A73D JSR $AB47) kein I/O-Fehler vorkommt und von daher das C-Flag immer gelöscht ist.

Genau diese Änderungen nimmt der oben vorgestellte Einzeiler vor, der im übrigen durch <RUN/STOP RESTORE> wieder aufgehoben werden kann. Dadurch wird nämlich wieder das alte (und fehlerhafte) Basic-ROM eingeschaltet.

Anmerkung der Redaktion: Unser Floppyspeeder »64'er-DOS« bringt bei einem List-Versuch des genannten Schutzes weder »Syntax Error noch »REMEND« sondern ein <SHIFT+L>, wie es ja auch richtig sein sollte.

(Florian Müller/tr)

<RESTORE> — Die Prügeltaste

Bei allen (zumindest uns bekannten) C 64-Computern braucht man bei der <RESTORE>-Taste einen sehr harten Anschlag, um überhaupt eine Reaktion zu erhalten. Da dieser durchaus störende Umstand nicht etwa auf einem Fehler in der Tastaturmechanik beruht, haben wir uns einmal den zuständigen Teil des Schaltplanes angesehen. Demnach befindet sich in der Restore-Leitung ein Kondensator C 38 (zu finden an der vorderen, linken Ecke der Computerplatine), der von Commodore mit 51 pF eindeutig zu klein dimensioniert ist, um das nachfolgende Timer-IC zu triggern. Nach Austausch dieses Kondensators gegen einen einfachen 10-nF Keramiktyp ist die <RESTORE >-Taste ebenso leichtgängig wie jede andere Taste auch.

(Arne Wohlfart/tr)

Musik am User-Port

Dieses Programm gibt einen Ton in der gewünschten Frequenz am User-Port aus. Als Vorbereitung nimmt man einen Lautsprecher und verbindet ihn mit den Anschlüssen GND und Pb6. Dann gibt man folgendes Programm ein:

10 POKE 56590,7
20 INPUT"Hertz :";he
30 h=985248.4/he:hi=INT(h/256):lo=h-hi*256
40 POKE 56580,lo:POKE 56581,hi

Erklärung:

In Zeile 10 wird der Timer A des CIA2 gestartet und ein Unterlauf an Pb6 des User-Ports ausgegeben. In Zeile 20 wird die Frequenz des Tons eingegeben. Zeile 30 rechnet die Frequenz mit Hilfe der Taktfrequenz (985248,4 kHz) in Timerwerte um. In Zeile 40 werden diese Timerwerte in die Zählregister von Timer A gePOKEt.

Zur Umrechnung der Frequenz:

Nehmen wir an, wir wollen alle 60stel Sekunde einen Interrupt (also einen Timerunterlauf) verursachen, wie dies zum Beispiel beim Systeminterrupt der Fall ist. Dann berechnen wir die Timerwerte nach folgender Rechnung:

Timerwerte = Taktfrequenz * 1/t, dabei ist t die Anzahl der Unterläufe. Für unser Beispiel würde das bedeuten:

Timerwerte = Taktfrequenz * %o bei einer Taktfrequenz von 985248.4 gibt das als Timerwert 16420.8. Diese Zahl wird in LSB und MSB erteilt und in die Zählregister gePOKEt. Nun wird alle 60stel Sekunde ein Unterlauf erzeugt. Dieser Unterlauf wird am User-Port ausgegeben (an Pb6) und erzeugt im Lautsprecher ein Knacken. Aufgrund der hohen Frequenz erscheint dieses Knacken als gleichmäßiger Ton.

Zum Bereich der Frequenz sei gesagt, daß er von 16 Hz bis zirka 20000 Hz reicht. Nach oben hin wird die Tonausgabe immer ungenauer, da die Stufung der Zählregister in 255er-Schritten zu ungenau ist.

Zur Ergänzung sei gesagt, daß diese Tonausgabe an einem weiteren Pin des User-Ports möglich ist: Es ist dies der Pin Pb7. Dabei müssen nur die entsprechenden Register von Timer B des CIA2 angesteuert und ein zweiter Lautsprecher angeschlossen werden.

(Dirk Trossen/tr)

Tempo für die RS232-Schnittstelle

Wie inzwischen bekannt, lassen sich alle Parameter der internen RS232-Schnittstelle durch ein entsprechendes Bit-Muster im Steuerregister (665) und Kontrollregister (666) einstellen. Die Übergabe der Parameter erfolgt beim Öffnen der Schnittstelle mit einem OPEN-Befehl unter der Gerätenummer 2.

Möchte man nun in einem laufenden Programm die Bedingungen Parität, Anzahl der Stopp-Bits und Datenwortlänge ändern, so kann dies durch Verändern der entsprechenden Bitwerte im Steuer- und Kontrollregister jederzeit geschehen. Will man jedoch die Übertragungsgeschwindigkeit in Bit pro Sekunde wechseln und setzt die korrespondierenden Bits neu, so stellt man fest, daß dies ohne Wirkung bleibt. Eine andere Geschwindigkeit läßt sich nur bei einem erneuten Initialisieren mit OPEN... einstellen. Dieser Befehl löscht aber gleichzeitig alle Variablen, so daß dann sowieso das Programm abgebrochen wird.

Eine Untersuchung der ROM-Routinen brachte die Ursache zutage. Beim Eröffnen der Schnittstelle werden die Speicherzellen $299 und $29A mit Konstanten versehen, die je nach eingestellten Bit pro Sekunde aus einer Tabelle entnommen werden. Diese Konstanten steuern den Timer im 6522 und damit die Taktrate. Beider Bearbeitung der Schnittstelle werden jetzt nur noch die Speicherzellen $299 und $29A ausgewertet, daher bleibt eine nachträgliche Änderung im Steuerregister wirkungslos.

Das Problem läßt sich dadurch lösen, indem man nachträglich noch einmal den Teil der OPEN-Routine anspringt, wo die Konstanten der Übertragungsgeschwindigkeit zugeordnet werden, Eine geeignete Einsprungstelle ist die Adresse 62499 ($F423). Man ändert also die entsprechenden Bits im Steuerregister und fügt anschließend an: SYS 62499.

(Dieter Laues/tr)

EOR in Basic

Wir haben eine Möglichkeit gefunden, in Basic ein »exclusiv-oder« zu simulieren. Dazu muß im Programm einfach die Zeile »DEF FNa(e)=((NOTx)ANDy)OR((NOTy)ANDx)« erscheinen. Dann setzt man die Variablen x und y auf die zu verknüpfenden Werte und ruft die Funktion mit einem beliebigen Parameter für e auf. Die Idee kam aus einem Digitalelektronikbuch, in dem eine EXOR-Schaltung durch Oder-, Nicht- und Und-Gatter aufgebaut wurde.

(Jens Vöcker/tr)

»Epson-Support« ohne Line-Feed

Im Sonderheft 6/86 ist ein Grafik-Programm abgedruckt, 6Epson-Support«), indessen Beschreibung angegeben wird, daß Auto-Line-Feed abgeschaltet werden muß. Ich habe das Programm abgetippt, und sann sofort auf Abhilfe. Das Ergebnis lautet: POKE50326,32 und ALF kann weiter eingeschaltet bleiben.

(Alfred Jäger/tr)

Die Musik von »Elite«

Ich habe einen Tip für alle diejenigen, die bei dem Spiel »Elites die Musik vermissen. Es gibt bei der englischen Version von Elite nur ein Lied (von Johann Strauß), dagegen bei der deutschen Version noch ein Lied zusätzlich (die Anfangsmusik). Wenn man das Spiel mit <INST/DEL> angehalten hat, kann man mit der Taste <M > lediglich das Start- und Andockrauschen ein/ausschalten. Was nicht in der Beschreibung steht, ist, daß man mit der Taste <X> in einen Modus kommt, indem man die Musik im Hintergrund ein-/ausschalten kann, bestimmen kann, ob neben der Musik andere Geräusche zugelassen sind oder nicht, und (bei der deutschen Version) sogar zwischen zwei Liedern wählen kann.

Folgende Tasten haben obige Wirkung, wenn Elite angehalten wurde:

<X> = Modus ein-/ausschalten
<C> = Musik möglich/nicht möglich (beim nächsten Docken/Neustart wird die Musik automatisch ein-/ausgeschaltet)
<M> = Musik sofort ein-/ausschalten
<B> = Geräusche während Musik ein-/ausschalten
<E> = (nur deutsche Version) Wahl zwischen zwei Liedern

Vielleicht weiß jemand, welche Bedeutung die <D>-Taste hat, denn auch bei ihr hört man das typische Klickgeräusch.

(Torsten Tiedemann/tr)

Der Bildschirm als liniertes Blatt

Es ist oft recht ärgerlich, wenn man am Bildschirm des C 64 arbeitet und, wenn Rahmen und Hintergrund gleichfarbig sind, nicht weiß, wo die letzte Zeile ist und einem auf einmal die ganze Sache nach oben wegscrollt. Für solche und ähnliche Fälle ist das Programm »Liniertes Blatt« (Listing 1) wie geschaffen. Durch eine geniale Raster-Interrupt-Routine erreichen Sie nämlich dasselbe wie wenn Sie mit Filzstift auf der Mattscheibe am Ende jeder Zeile eine Linie ziehen würden. Eingegeben wird das äußerst kurze Programm mit dem MSE und gestartet mit SYS49206. Es liegt von $C000 bis $C05a im Speicher. Die Hintergrundfarbe muß von jetzt an nach 49175 gePOKEt werden; die Farbe der Linien ist in 49163 festgelegt.

(Günter Burgstaller/tr)
PROGRAMM : LINIERTES BLATT C000 C05A
-----------------------------------
C000 : EA EA EA EA EA A9 01 8D   92
C008 : 19 D0 A9 00 8D 21 D0 A2   5E
C010 : 06 EA EA CA D0 FB A9 06   3F
C018 : 8D 21 D0 A5 02 C9 F9 F0   57
C020 : 0B 18 69 08 85 02 8D 12   55
C028 : D0 4C 81 EA A9 39 85 02   5A
C030 : 8D 12 D0 4C 31 EA 78 A9   24
C038 : 39 85 02 8D 12 D0 AD 11   E7
C040 : D0 29 7F 8D 11 D0 A9 01   77
C048 : 8D 0D DC 8D 1A D0 A9 00   13
C050 : A2 C0 8D 14 03 8E 15 03   37
C058 : 58 60                     84
Listing 1. »Liniertes Blatt«

Kursivschrift am Bildschirm

Kursivschrift oder »Italics« gehört heutzutage schon zur Standardausrüstung eines durchschnittlichen Druckers. Mit dem gleichnamigen Programm (Listing 2) kann der C 64-Besitzer diese Schriftart auch auf dem Bildschirm genießen. Eine VIC-Interrupt-Routine setzt ohne Veränderung des Zeichensatzes diesen Effekt für Sie in Szene. Eingegeben wird wie gewohnt mit dem MSE, die Inbetriebnahme erfolgt durch SYS49197. Das Progrämmchen belegt die Speicherstellen $C000 bis $C031.

(Günter Burgstaller/tr)
PROGRAMM : KURSIVSCHRIFT  C000 C051
-----------------------------------
C000 : EA EA EA EA EA A9 01 8D   92
C008 : 19 D0 AD 16 D0 49 01 8D   2E
C010 : 16 D0 A5 02 C9 F6 F0 0B   66
C018 : 18 69 04 85 02 8D 12 D0   0D
C020 : 4C 81 EA A9 32 85 02 8D   8F
C028 : 12 D0 4C 31 EA 78 A9 32   59
C030 : 85 02 8D 12 D0 AD 11 D0   BC
C038 : 29 7F 8D 11 D0 A9 01 8D   20
C040 : 0D DC 8D 1A D0 A9 00 A2   02
C048 : C0 8D 14 03 8E 15 03 58   83
C050 : 60                        62
Listing 2. »Kursivschrift«

Der Super-Listschutz

Es handelt sich hier um eine ganz besondere Art von Listschutz, welche das Auflisten zwar nicht verhindert, aber den unbefugten Eindringling mit den blanken Zeilennummern konfrontiert. Nehmen wir an, Sie hätten ein Basic-Programm geschrieben und wollen es ganz oder nur bestimmte Teile (zum Beispiel Algorithmen) vor neugierigen Blicken schützen. Sie laden dazu Ihr Programm und H.l.DE. (Listing 3) und starten dieses mit SYS49152. Achtung: Ihr Programm muß 100prozentig in den Basic-Zeilen untergebracht sein. Maschinenprogramme, die nur eine Basic-Kopfzeile haben, können nicht bearbeitet werden. Es ist übrigens egal, ob Sie H.I.DE. vor oder nach Ihrem Programm laden, da bei seinem Start die Basic-Endezeiger wieder gerichtet werden und so ein »OUT OF MEMORY ERROR« verhindert wird. Nach kurzer Zeit hat das Maschinenprogramm seine geheimnisvolle Arbeit getan, und Sie dürfen jetzt versuchen, Ihr Basic-Programm zu LISTen. j

Beispiel:

(vorher)

10 A$="NIZAGAM RE'46"
20 FOR T=LEN(A$) TO 1 STEP -1
30 PRINT MID$(A$,T,1);:REM GEHEIMER ALGORITHMUS
40 NEXT T
SYS 49152

(nachher)

10
20
30
40

Es ist verblüffend, nicht? Sie können natürlich auch Zeilen stehenlassen. Sie teilen das dem Programm mit, indem Sie jeder Zeile, die affen b@ vo 50 @REM COPYRIGHT BY 64er 1986 wird nicht verändert. Nur der Klammeraffe wird gelöscht. So lassen sich Bemerkungen, die den Neugierigen empfangen sollen (zum Beispiel GET OUT OF HERE!) leicht anbringen. Noch besser sieht'saus, wenn die Zeile nicht angesprungen wird, und so das REM entfallen kann!

Eine Einschränkung: Die erste Zeile darf nicht stehenbleiben! Lassen Sie notfalls eine REM-Zeile verschwinden.

Ihr Programm können Sie jetzt ganz normal speichern. Nach dem Laden muß nichts mehr eingegeben werden, wie bei anderen Listschutz-Versuchen üblich, die meist ziemlich sinnlos sind, wenn der Unbefugte erst einen POKE eingeben muß, um abgewiesen zu werden.

Wenn Sie nun auf eine Erklärung des Phänomens gewartet haben, muß ich Sie enttäuschen, denn was ist schon ein Listschutz, wenn er überall bekannt ist? Versuchen Sie, es selber herauszufinden. Wie Sie sicher merken werden, kann es je nach Programmlänge etwas länger dauern, bis H.l.DE. fertig ist. HI.DE. informiert Sie regelmäßig, welche Zeile er gerade bearbeitet. So sehen Sie auch, daß er bei längeren Programmen relativ lange für eine Zeile braucht.

Nur so viel: es liegt daran, daß extrem viel im Speicher verschoben werden muß. Deshalb sollte man bei seinen Programmen wenn möglich folgendes beachten:

Sollte Ihr Programm zu lang sein, meldet sich H.I.DE. und ..sagt es Ihnen. Normalerweise sind Programme bis 32 KByte möglich. Beachten Sie auch, daß Sie das Programm jetzt nicht mehr editieren können und die Zeilen gelöscht werden, wenn Sie mit dem Cursor auf die Zeilennummer gehen und <RETURN> drücken!

(Frank Hund/tr)
PROGRAMM : H.I.D.E.       C000 C19D
-----------------------------------
C000 : 20 33 A5 A5 22 18 69 02   64
C008 : 85 2D A5 23 69 00 85 2E   FB
C010 : A5 2B 85 FB A5 2C 85 FC   F7
C018 : A9 00 8D 98 C1 8D 99 C1   AA
C020 : 20 2D C1 A0 00 B1 FB 8D   F4
C028 : 9A C1 C8 B1 FB 8D 9B C1   29
C030 : D0 08 AD 9A C1 D0 03 4C   0A
C038 : C5 C0 20 AC C0 A0 04 B1   7F
C040 : FB C9 40 F0 42 A0 00 18   A7
C048 : AD 98 C1 69 06 8D 98 C1   92
C050 : AD 99 C1 69 00 8D 99 C1   BE
C058 : 20 93 C0 18 A5 FB 69 04   5D
C060 : 85 FB A5 FC 69 00 85 FC   92
C068 : 4C D9 C0 A0 00 98 91 FB   E8
C070 : C8 A9 3A 91 FB C8 C0 06   E3
C078 : D0 F9 AD 9A C1 85 FB AD   97
C080 : 9B C1 85 FC 4C 23 C0 A9   31
C088 : 20 91 FB A0 00 20 93 C0   55
C090 : 4C 7A C0 18 AD 9A C1 6D   DE
C098 : 98 C1 8D 9A C1 91 FB AD   BB
C0A0 : 9B C1 6D 99 C1 8D 9B C1   25
C0A8 : C8 91 FB 60 A2 00 BD 8D   80
C0B0 : C1 20 D2 FF E8 C9 00 D0   B4
C0B8 : F5 A0 02 B1 FB AA C8 B1   50
C0C0 : FB 20 CD BD 60 18 A5 2B   AA
C0C8 : 69 05 85 FB A5 2C 69 00   F6
C0D0 : 85 FC A0 00 A9 41 91 FB   DE
C0D8 : 60 A5 2D 85 FD A5 2E 85   D8
C0E0 : FE 18 A5 2D 69 06 85 2D   31
C0E8 : A5 2E 69 00 85 2E C9 A0   31
C0F0 : F0 73 20 22 C1 A0 00 B1   6B
C0F8 : FD A0 06 91 FD C6 FD A5   52
C100 : FD C9 FF D0 02 C6 FE A5   99
C108 : FD C5 FB D0 E8 A5 FE C5   44
C110 : FC D0 E2 20 19 C1 4C 6B   D9
C118 : C0 E6 FB A5 FB D0 02 E6   1B
C120 : FC 60 C6 FB A5 FB C9 FF   DF
C128 : D0 02 C6 FC 60 A2 00 BD   E1
C130 : 3B C1 20 D2 FF E8 C9 00   1D
C138 : D0 F5 60 11 12 48 2E 49   EC
C140 : 2E 44 2E 45 2E 20 56 33   68
C148 : 2E 32 92 0D 4D 4F 4D 45   E5
C150 : 4E 54 20 42 49 54 54 45   2C
C158 : 20 21 0D 11 5A 45 49 4C   FC
C160 : 45 20 3A 20 00 A2 00 BD   D9
C168 : 75 C1 20 D2 FF E8 C9 00   8F
C170 : D0 F5 4C C5 C0 0D 12 53   6A
C178 : 4F 52 52 59 2C 20 50 52   5A
C180 : 47 20 5A 55 20 4C 41 4E   1F
C188 : 47 2E 92 11 00 0D 91 1D   96
C190 : 1D 1D 1D 1D 1D 1D 1D 00   56
C198 : 00 00 00 00 0D            2E
Listing 3. »H.I.D.E.«, der Super-Listschutz
100 rem *****************************
110 rem * quelltext fuer            *
120 rem * profi-ass oder formel-64  *
130 rem * programm : h.i.d.e. v3.2  *
140 rem *                           *
150 rem * written by...frank hund   *
160 rem *              hoehenweg 8  *
170 rem *         5200 siegburg 1   *
180 rem *                           *
190 rem * (c) 1986 f.h.             *
200 rem *                           *
210 rem * start $c000=49152         *
220 rem *****************************
230 :
240 sys9*4096
250 .opt oo
260 * = $c000
270 ;
280 jsr 42291        ;nichts geht
290 lda 34           ;ueber ein gutes
300 clc              ;'old' zu anfang.
310 adc #$02         ;h.i.d.e. wird
320 sta 45           ;dadurch
330 lda 35           ;anwender-
340 adc #$00         ;freundlicher!
350 sta 46           ;
360 lda 43            ;initialisieren
370 sta $fb           ;
380 lda 44            ;
390 sta $fc           ;
400 lda #$00          ;
410 sta zaehlerlow    ;
420 sta zaehlerhigh   ;
430 jsr hello         ;moment bitte !
440 ;
450 mainloop ldy #$00 ;
460 lda ($fb),y       ;adresse fuer
470 sta adresselow    ;naechste zeile
480 iny               ;lesen
490 lda ($fb),y       ;
500 sta adressehigh
510 bne nostop        ;pruefen auf
520 lda adresselow    ;ende
530 bne nostop        ;
540 jmp fertig
550 ;
560 nostop jsr zout ;zeilennummer
570 ;               ;ausgeben...
580 ldy #$04          ;wird diese
590 lda ($fb),y       ;zeile
600 cmp #"@"          ;verschont "?"
610 beq nohide        ;
620 ldy #$00          ;nein ! (hehe...)
630 clc               ;hilfszaehler
640 lda zaehlerlow    ;um 6 erhoehen
650 adc #$06          ;
660 sta zaehlerlow    ;
670 lda zaehlerhigh   ;
680 adc #$00          ;
690 sta zaehlerhigh   ;
700 ;
710 jsr verknuepfe    ;addieren und
720 ;                 ;zurueckschreiben
730 clc
740 lda $fb           ;4 bytes
750 adc #$04          ;(adresse,
760 sta $fb           ;zeilennummer)
770 lda $fc           ;ueberspringen
780 adc #$00          ;
790 sta $fc
800 jmp copit         ;k o p i e r e n
810 ;
820 back ldy #$00     ;entstandenen
830 tya               ;zwischenraum
840 sta ($fb),y       ;mit
850 iny               ;1* 00
860 lda #$3a          ;5* 3a
870 fuell sta ($fb),y ;auffuellen
880 iny               ;
890 cpy #$06          ;
900 bne fuell
910 set lda adresselow;vektor auf
920 sta $fb           ;naechste, neu-
930 lda adressehigh   ;errechnente
940 sta $fc           ;zeile
950 jmp mainloop      ;und von anfang
960 ;
970 nohide lda #$20   ;zeile wird
980 sta ($fb),y       ;verschont.
990 ldy #$00          ;marke (@) wird
1000 jsr verknuepfe   ;beseitigt...
1010 jmp set          ;
1020 ;
1030 verknuepfe clc   ;unteroutine :
1040 lda adresselow   ;
1050 adc zaehlerlow   ;berechnung der
1060 sta adresselow   ;naechsten
1070 sta ($fb),y      ;adresse.
1080 lda adressehigh  ;
1090 adc zaehlerhigh  ;
1100 sta adressehigh  ;
1110 iny              ;
1120 sta ($fb),y      ;
1130 rts
1140 ;
1150 zout ldx #$00    ;routine
1160 llp3 lda pos,x   ;aktuelle
1170 jsr $ffd2        ;zeilennummer
1180 inx              ;ausgeben.
1190 cmp #$00         ;
1200 bne llp3         ;
1210 ldy #$02         ;
1220 lda ($fb),y      ;
1230 tax              ;
1240 iny              ;
1250 lda ($fb),y      ;
1260 jsr $bdcd        ;
1270 rts
1280 ;
1290 fertig clc       ;fertig...fast!
1300 lda 43           ;wichtig:
1310 adc #$05         ;ein 'a' in der
1320 sta $fb          ;1. zeile.
1330 lda 44           ;ausfuehrlich
1340 adc #$00         ;gemacht damit
1350 sta $fc          ;flexibel fuer
1360 ldy #$00         ;alle speicher-
1370 lda #$41         ;bereiche
1380 sta ($fb),y
1390 rts              ;back to basic
1400 ;
1410 copit lda 45     ;kopierroutine
1420 sta $fd          ;=============
1430 lda 46           ;
1440 sta $fe          ;initialisieren:
1450 clc              ;-vektoren
1460 lda 45           ; setzen
1470 adc #$06         ;-speicherende
1480 sta 45           ; hochsetzen
1490 lda 46           ;
1500 adc #$00         ;
1510 sta 46           ;
1520 cmp #$a0         ;prg zu gross
1530 beq error        ;geworden"?"
1540 jsr deb
1550 ;
1560 begin ldy #$00   ;
1570 lda ($fd),y      ;hier wird der
1580 ldy #$06         ;speicher
1590 sta ($fd),y      ;zwischen der
1600 dec $fd          ;aktuellen
1610 lda $fd          ;'arbeitsstelle'
1620 cmp #$ff         ;und dem
1630 bne no           ;programmende
1640 dec $fe          ;um 6 bytes
1650 no lda $fd       ;nach hinten
1660 cmp $fb          ;verschoben
1670 bne begin        ;
1680 lda $fe          ;
1690 cmp $fc          ;
1700 bne begin        ;
1710 jsr inb
1720 jmp back         ;zurueck
1730 ;
1740 inb inc $fb      ;kleine
1750 lda $fb          ;subroutinen
1760 bne noi          ;
1770 inc $fc          ;
1780 noi rts          ;
1790 ;                ;
1800 deb dec $fb      ;
1810 lda $fb          ;
1820 cmp #$ff         ;
1830 bne not          ;
1840 dec $fc          ;
1850 not rts          ;
1860 ;
1870 hello ldx #$00
1880 llp lda words,x
1890 jsr $ffd2
1900 inx
1910 cmp #$00
1920 bne llp
1930 rts
1940 words .asc "{down}{rvon}h.i.d.e. v3.2{rvof}"
1950 .byt $0d
1960 .asc "moment bitte !"
1970 .byt $0d
1980 .asc "{down}zeile : "
1990 .byt $00
2000 error ldx #$00
2010 llp2 lda words2,x
2020 jsr $ffd2
2030 inx
2040 cmp #$00
2050 bne llp2
2060 jmp fertig
2070 words2 .byt $0d
2080 .asc "{rvon}sorry, prg zu lang.{rvof}{down}"
2090 .byt $00
2100 pos .byt $0d
2110 .asc "{up}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}" : .byt $00
2120 ;
2130 zaehlerlow  .byt 0 ;hilfszeiger
2140 zaehlerhigh .byt 0 ;
2150 adresselow  .byt 0 ;
2160 adressehigh .byt 0 ;

Regelbares Dauerfeuer

Ich habe einen Quickshot II-Joystick, der mit einfachem Dauerfeuer ausgestattet ist. Durch das Auswechseln eines Widerstandes gegen ein Poti (Bild 2) kann das Dauerfeuer geregelt werden. Hardwareschäden sind während der vier Wochen Dauertest nicht aufgetreten

(K. Pichlmair/tr)
Zwei Zeichnungen des geöffneten Joystick-Innenraums, links mit Widerstand R1, rechts mit einem Potentiometer
Bild 2. Regelbares Dauerfeuer für den Quickshot II

Zahlen eingeben mit dem Joystick

In Ausgabe 6/86 auf Seite 77 wurde bereits ein solches Programm veröffentlicht. Esläßt sich aber wesentlich kürzer und übersichtlicher schreiben (siehe Listing 4). Der Joystick wird in Port 1 gesteckt. Der Feuerknopf beendet die Eingabe. Danach wird die eingegebene Zahl berechnet und in der Variablen W gespeichert.

Die Eingabe kann mit Hilfe von PRINT-Befehlen beliebig positioniert werden. Der POKE 198,0 in der letzten Zeile löscht den Tastaturpuffer, der wegen des Joysticks in Port 1 wirre Zeichen enthält.

(Andreas Kaiser/tr)
60000 dim w(6)
60010 print"eingabe:";
60020 print"000000{left}";:a$="{down}{left}^{up}{left}":s=6
60030 a=peek(56321)
60040 ifa=254andw(s)<9thenw(s)=w(s)+1
60050 ifa=253andw(s)>0thenw(s)=w(s)-1
60060 ifa=251ands>1thens=s-1:print"{down} {up}{left}{left}";
60070 ifa=247ands<6thens=s+1:print"{down} {up}";
60080 ifa=239then60110
60090 printright$(str$(w(s)),1)a$;
60100 goto60030
60110 w=w(6)+w(5)*10+w(4)*100+w(3)*1000+w(2)*10000+w(1)*100000
60120 print:print
60130 print"wert:"w
60140 poke198,0
Listing 4. Verbesserte Zahleneingabe mit dem Joystick

Tip zu PrologicDOS

Über »POKE 781,133: SYS 58551« läßt sich aus einem Basic-Programm heraus das Disketteninhaltsverzeichnis auf den Bildschirm bringen (entspricht der <Fl>-Taste). Das Ganze läßt sich natürlich auch in Maschinensprache schreiben: »LDX #$85: JSR $E4B7«

(tr)
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →