Tips & Tricks für Profis

Wir können Ihnen als weltweit erste Computerzeitschrift eine wirklich vollständige POKE-Liste für den C 64 anbieten! Interessant ist auch ein Trick, um den $C000-Bereich für Basic-Programme zu nutzen.

Man möchte es nicht wahrhaben: Obwohl der C 64 nun schon drei Jahre alt ist, gibt es doch immer wieder ein paar unbekannte Tricks. Selbst die eingefleischten C 64-Profis geraten mitunter ins Staunen!

Vollständige POKE-Liste für den C 64!

Das in Listing 1 wiedergegebene Programm liefert dem Benutzer eine nach Wissen und Gewissen der Autoren wirklich vollständige Liste aller bekannten und unbekannten POKEs für den C 64. Es beantwortet damit die allerletzten Fragen der C 64-Fan-Gemeinde.

Programmtechnisch sei auf die aufwendige Seiten- und Zeilenformatierung hingewiesen, die ein angenehmes Druckbild auf dem (angeschlossenen) Drucker gewährleisten. Allerdings sollte dieser Drucker vor dem »RUN«-Befehl mit reichlich Papier versorgt werden. Abtipphinweise: Bitte gehen Sie bei der Eingabe dieses äußerst komplizierten Listings sorgfältig vor und verwenden Sie unbedingt den Checksummer. Nur dann kann ein fehlerfreier Programmlauf gewährleistet werden!

5 z$="a l l e   pokes fuer den c 64, von h. buetzer und p. kittel"
6 z$=z$+"                "+chr$(13)
50 open1,4:zz=99:sz=0
70 fori=0to65535:forj=0to255
80 a$="poke"+mid$(str$(i),2)+","+mid$(str$(j),2)
81 iflen(a$)+len(z$)<79thenz$=z$+":"+a$:goto85
83 zz=zz+1:ifzz>60thenzz=0:sz=sz+1:print#1,chr$(12);"seite";sz:print#1
84 print#1,z$:z$=a$
85 next:next:print#1,z$
90 close1:end
Listing 1. »Vollständige POKE-Liste«.
(Dr. Peter Kittel, Hartmut Bützer/tr)

»Device not present Error«

Mit folgender Befehlsfolge können Sie überprüfen, ob Floppy oder Drucker am seriellen Bus angeschlossen und eingeschaltet sind:
OPEN lf,ga,sa: CLOSE lf: IF ST < 0 THEN PRINT"Fehler!":STOP

Bedeutung der Variablen:

lf logische Filenummer; beliebig, sollte nicht anderweitig verwendet werden.
ga: Geräteadresse des zu überprüfenden Geräts, üblicherweise 4 für den Drucker, 8 oder 9 für die Floppy.
sa: Sekundäradresse, darf bei der Floppy nicht 15 sein, da sonst der CLOSE-Befehl auch alle anderen Floppy-Kanäle schließt; kann beim Drucker entfallen.
ST ist die Computer-interne Statusvariable, in der das Betriebssystem Fehler bei der Ein- und Ausgabe festhält.

Funktionsweise: Der OPEN-Befehl aktualisiert, da kein Filename angegeben ist, nur die Computer-interne Tabelle der geöffneten Files. Daher kann der OPEN-Befehl auch niemals einen »DEVICE NOT PRESENT ERROR« nach sich ziehen. Entscheidend ist der CLOSE-Befehl: Da die in dieser Tabelle eingetragene Geräteadresse auf den seriellen Bus weist, wird auf jeden Fall auf den Bus zugegriffen und dabei festgestellt, daß das Gerät nicht angeschlossen beziehungsweise eingeschaltet ist. Dieser Zustand setzt Bit 7 der Statusvariablen ST. Der Basic-Interpreter verzichtet beim CLOSE-Befehl aufdie Überprüfung dieser Systemvariablen, also tritt kein »?device not present error« auf. Wird ST dann von Basic aus angesprochen, wird Bit 7 als Vorzeichenbit aufgefaßt, folglich enthält ST bei fehlendem/ausgeschaltetem Gerät einen negativen Wert und der IF-Befehl wird nach dem THEN fortgesetzt.

Übrigens: Kannten Sie schon diesen Betriebssystemfehler: Geben Sie bei ausgeschalteter Floppy ein:
10 OPEN 1, 8, 15 : INPUT#1, E, E$
RUN

Der Computer wartet, bis Sie die Floppy einschalten, und gibt dann erst »?device not present error« aus.

(Rainer Perske/tr)

Hardcopy für Star SG/10, 15

Die »Hardcopyroutine auf Tastendruck für Epson-Drucker« aus 64’er, Ausgabe 1/86, läßt sich für den STAR SG/10,15-Drucker modifizieren.

Programm »Hardcopy.Obj.« mit,8,l laden, »SYS 49152« eingeben und danach im Direktmodus folgende POKEs eingeben:
POKE49441,75 : POKE49442,27 : POKE49443,13 : POKE49444,49 : POKE 49445,27.

Soll noch statt der F1-Taste, die in vielen Programmen zur Auswahl in Menüs verwendet wird, eine andere Taste gewählt werden (ich verwende die»= «-Taste), so muß noch POKE 49168,53 eingegeben werden.

(Heden Wolfgang/tr)

Basic-Programm im $C000-Bereich?

In der Tat kann es manchmal bei Verwaltung größerer Datenmengen beim C 64 sinnvoll sein, den für Basic-Programme normalerweise nicht zugänglichen Bereich $C000 bis $D000 (C 64) beziehungsweise $A000 bis $C000 (VC 20) mit dem Basic-Programm zu belegen und damit den Grundspeicher voll für Variablenfelder zur Verfügung zu haben. Für die Programmeingabe (beziehungsweise zum Laden) lautet die POKE-Kombination:
POKE44,192:POKE56,208:POKE49152,0:NEW

Die Programmzeile 0 eines solchen Programms muß dann lauten:
0 POKE56,PEEK(644):POKE45,3:POKE46,PEEK(642):CLR

Achtung: Nach »RUN« kann zwar noch mit »LIST« das Programm abgefragt werden, aber Änderungen im Programmlisting führen unweigerlich zum Systemabsturz (hängt mit der Verschieberoutine für Basic-Zeilen zusammen)! Für den VC 20 gilt für die Programmverlegung nach $A000-$C000 (sofern dieser Bereich mit einer RAM-Erweiterung belegt ist) für die Programmeingabe die Befehlsfolge POKE 44,160:POKE 56, 192:POKE 40960,0: NEW. Die Zeile 0 gilt unverändert auch beim VC 20.

(Barnim König/tr)

Grafikzeichen in der ID

Durch folgenden kleinen Trick ist es möglich, auch Grafikzeichen in der ID einer Diskette zu verwenden: Man schiebt beim Formatieren vor der ID noch ein Anführungszeichen (CHR$ (34)) ein:
OPEN 1,8,15,"N:NAME" + CHR$(34) + ",ID":CLOSE1
Der Kreativität sind keine Grenzen gesetzt.

(Wolf Schenk/tr)

Hypra-Platos und Görlitz-Interface

Laden Sie nun zuerst einmal das Programm »2. PRG« mit dem MSE. Ist das geschehen, ist mit dem Befehl »CTRL-N« auf den Eingabemodus zu schalten. Als Startadresse geben Sie »9240« ein, tippen die Zeile »9240« aus Ausgabe 11/85 ab, jedoch mit dem Unterschied, daß Sie die vierte Zahl (0A) durch »0D« ersetzen. Als Prüfsumme ist statt 40 A0 einzusetzen. Mit der Zeile »9278« ist genauso zu verfahren. Ersetzen Sie hier das siebte Byte (0A) ebenfalls durch »0D«. Die Prüfsumme ändert sich. Statt »26« muß hier »32« eingesetzt werden. Speichern Sie das Programm. Als Sekundäradresse ist nun im Druckertreiber die $14 zu empfehlen.

(Achim Hübner/tr)

Computer-Logbuch

Dieses Assemblerprogramm (Listing 2) dient dazu, die aktuelle Speicherstelle im Programmlauf in die linke obere Ecke des Bildschirms zu schreiben.

Mich hatte es gereizt, bei fremden Programmen in Maschinensprache die zu den verschiedenen Routinen gehörenden Adreßbereiche zu lokalisieren.

Ursprünglich wurde bei jedem zehnten Interrupt die Adresse aus den Speicherstellen 105 und 106 gelesen und in die oberste Zeile des Bildschirms geschrieben.

Durch den schnellen Wechsel der Anzeige war dies jedoch mühsam abzulesen. Aus diesem Grund habe ich jede zweite Ausgabe in die zweite Zeile umgeleitet. Nun ist die Ablesung kein Problem mehr. Es ist schon interessant, bei dieser Adressenfolge zuzuschauen. Besonders lehrreich ist es für Anfänger und Fortgeschrittene, zu sehen, welche Bereiche im Kernel angesprungen werden.

Wenn zum Beispiel der blinkende Cursor auf eine Eingabe wartet, so kann man in bunter Folge die Adressen zwischen $E5CA bis $E5D4 Revue passieren sehen.

Denkbar wäre noch, die Ablesung bei jedem Interrupt vorzunehmen, und die Adressen auf den Drucker zu geben. Dabei könnten alle Adressen im ROM-Bereich aussortiert werden, wenn man sich auf die Struktur eines noch unbekannten Programms konzentrieren möchte.

PROGRAMM : OUTADR         C000 C099
-----------------------------------
C000 : 78 A9 0D A0 C0 8D 14 03   73
C008 : 8C 15 03 58 60 CE 96 C0   43
C010 : AD 96 C0 C9 0F F0 11 AD   8A
C018 : 96 C0 C9 0A F0 25 AD 96   DE
C020 : C0 C9 01 F0 39 4C 31 EA   B4
C028 : A0 03 A9 0E 99 00 D8 88   84
C030 : 10 F8 A0 00 BD 06 01 20   35
C038 : 66 C0 BD 05 01 20 66 C0   3B
C040 : 4C 31 EA A0 03 A9 0E 99   DC
C048 : 28 D8 88 10 F8 A0 00 BD   10
C050 : 06 01 20 7E C0 BD 05 01   BF
C058 : 20 7E C0 4C 31 EA A9 10   A2
C060 : 8D 96 C0 4C 31 EA 48 4A   12
C068 : 4A 4A 4A 20 71 C0 68 29   7F
C070 : 0F C9 0A 90 02 E9 39 69   20
C078 : 30 99 00 04 C8 60 48 4A   3B
C080 : 4A 4A 4A 20 89 C0 68 29   19
C088 : 0F C9 0A 90 02 E9 39 69   38
C090 : 30 99 28 04 C8 60 10 00   E7
C098 : 41                        B4
Listing 2. »Outadr« zeigt ständig den Prozessor-Programmzähler an.
(Ralf Störmer/tr)

Absturz-POKES

Durch »Verbiegen« diverser Vektoren lassen sich einige interessante Effekte erreichen:
POKE768,226:POKE769,252 — Reset nach Programmfehler oder Programmende (nicht im Direktmodus verwenden!)
POKE770,226:POKE771,252 — Reset nach Drücken der STOP-Taste (nicht im Direktmodus verwenden!)
POKE816,226:POKE817,252 — Reset nach Eingabe des LOAD-Befehls

Mit diesem Trick lassen sich noch andere Zeiger verändern. Wo diese Zeiger im Speicher des C64 liegen, läßt sich aus der Speicherbelegungstabelle des Handbuchs (Anhang Q, Seite 160) entnehmen.

Eine andere Möglichkeit ist, anstatt eines Resets einen Overflow-Error auszulösen. Dafür muß man die Werte 92 und 189 anstatt 226 und 252 in die entsprechenden Speicherstellen POKEn. Das läßt sich gut bei LOAD (816/817) und SAVE (818/819) machen. Vorsicht bei 768/769 und 770/771! Bei diesen Speicherstellen funktioniert der Trick nicht. Bei 770/771 wird zum Beispiel nach der Ready-Meldung immer wieder die Overflow-Routine angesprungen!

(Stefan Pohl/tr)

Sortierroutine für zweidimensionale Felder

Array-Sort (Listing 3) wird absolut geladen (Sekundäradresse 1) und steht dann im Bereich $C000 bis $C31B. Es ist wegen einiger JMPs und JSRs nicht relokatibel. Aufgerufen wird die Sortierung mit SYS49152, Variable, wobei das $-Zeichen nicht angegeben wird.

Beispiele: SYS49152,A, oder SYS49152,NM, aber nicht SYS49152,A$. Bei zweidimensionalen Arrays muß vorher noch das Element der 2. Dimension, nach dem sortiert werden soll, in die Speicherstelle 780 gePOKEt werden.

Beispiel:

Eine kleine Adreßverwaltung besteht aus Y$(X,0)=Vorname, Y$(X,l)=Nachname, Y$(X,2) = Straße und Y$(X,3) = Ort.

So wird nun mit »POKE780,l:SYS48152,Y« das Array nach den Nachnamen sortiert.

Der POKE darf nicht entfallen, da sich in Zelle 780 zufällige Werte befinden!

Sollte das Array nicht dimensioniert oder das Element das in 780gePOKEtwird, nicht vorhanden sein, soführtdaszu der Fehlermeldung »Bad Subscript«. Im Programm werden einige Zeropage-Adressen und Teile des Kassettenpuffers verwendet, was jedoch für Basic nicht sehr von Belang ist.

PROGRAMM : ARRAY-SORT     C000 C31C
-----------------------------------
C000 : 85 B5 A9 00 8D 34 03 8D   6C
C008 : 35 03 20 73 00 8D 34 03   79
C010 : 20 73 00 C9 3A F0 0A C9   0A
C018 : 00 F0 06 8D 35 03 20 73   96
C020 : 00 20 4B C0 20 9B C0 A5   48
C028 : FB C9 01 D0 03 4C 17 C2   D7
C030 : 20 CD C0 A5 B5 C5 FC 10   B9
C038 : 5E C9 00 F0 03 20 9C C2   C2
C040 : 20 FD C0 A5 B5 F0 03 20   73
C048 : 9C C2 60 A5 2F 85 22 A5   05
C050 : 30 85 23 20 8B C0 A0 00   51
C058 : AD 34 03 D1 22 D0 15 C8   A9
C060 : AD 35 03 09 80 D1 22 D0   4B
C068 : 0B A5 22 8D 36 03 A5 23   D8
C070 : 8D 37 03 60 A0 02 B1 22   8B
C078 : 18 65 22 AA C8 B1 22 65   8E
C080 : 23 85 23 86 22 20 8B C0   D2
C088 : 4C 56 C0 A5 22 C5 31 D0   9B
C090 : 09 A5 23 C5 32 D0 03 4C   3C
C098 : 45 B2 60 AD 36 03 85 19   C8
C0A0 : AD 37 03 85 1A A0 04 B1   74
C0A8 : 19 85 FB C9 03 10 1B C8   6B
C0B0 : B1 19 99 F7 00 C0 08 30   DA
C0B8 : F6 A5 FC A6 FD 85 FD 86   A6
C0C0 : FC A5 FE A6 FF 85 FF 86   5C
C0C8 : FE 60 4C 48 B2 A9 00 85   96
C0D0 : 02 A5 FE 18 65 FE 90 03   FE
C0D8 : 20 F6 C0 65 FE 90 03 20   11
C0E0 : F6 C0 8D 38 03 A5 FF 18   2E
C0E8 : 65 02 65 FF B0 0C 65 FF   A9
C0F0 : B0 08 8D 39 03 60 E6 02   02
C0F8 : 18 60 4C 8A BB AD 36 03   AD
C100 : 18 69 09 85 22 AD 37 03   32
C108 : 69 00 85 23 A5 22 18 69   D6
C110 : 03 85 24 A5 23 69 00 85   1C
C118 : 25 20 A1 C1 A0 01 B1 22   0B
C120 : 99 56 00 B1 24 99 58 00   8B
C128 : C8 B1 22 99 56 00 B1 24   F9
C130 : 99 58 00 A0 00 B1 22 D1   C3
C138 : 24 30 02 B1 24 85 5B C9   9B
C140 : 00 F0 34 A0 00 B1 59 D1   70
C148 : 57 F0 08 B0 0B 20 BC C1   58
C150 : 4C 58 C1 C8 C4 5B D0 ED   98
C158 : A5 24 C5 5C D0 09 A5 25   42
C160 : C5 5D D0 03 4C 77 C1 A5   3B
C168 : 24 18 69 03 85 24 A5 25   AD
C170 : 69 00 85 25 4C 1C C1 A5   D7
C178 : 22 18 69 03 85 22 A5 23   A7
C180 : 69 00 85 23 A5 22 C5 5C   EA
C188 : D0 07 A5 23 C5 5D D0 01   36
C190 : 60 A5 22 18 69 03 85 24   5C
C198 : A5 23 69 00 85 25 4C 1C   14
C1A0 : C1 A5 22 18 6D 38 03 85   6F
C1A8 : 5C A5 23 6D 39 03 85 5D   CA
C1B0 : A5 5C 38 E9 03 B0 02 C6   1A
C1B8 : 5D 85 5C 60 A5 22 48 A5   D3
C1C0 : 23 48 A5 24 48 A5 25 48   CC
C1C8 : A6 FC 86 BE 20 05 C2 A5   E6
C1D0 : 22 18 6D 38 03 85 22 A5   91
C1D8 : 23 6D 39 03 85 23 B0 22   D9
C1E0 : A5 24 18 6D 38 03 85 24   45
C1E8 : A5 25 6D 39 03 85 25 B0   F5
C1F0 : 11 C6 BE D0 D7 68 85 25   4F
C1F8 : 68 85 24 68 85 23 68 85   57
C200 : 22 60 4C 7E B9 A0 00 B1   39
C208 : 22 AA B1 24 91 22 8A 91   E8
C210 : 24 C8 C0 03 30 F1 60 18   6D
C218 : AD 36 03 69 07 85 6E AD   80
C220 : 37 03 69 00 85 6F A0 00   8A
C228 : B1 6E F0 6F 85 22 C8 B1   2A
C230 : 6E 99 22 00 C0 02 D0 F6   41
C238 : A5 6E 85 71 A5 6F 85 72   75
C240 : 18 A5 71 69 03 85 71 90   F8
C248 : 02 E6 72 A0 00 B1 71 F0   A3
C250 : 3D 85 4D C5 22 90 02 A5   56
C258 : 22 85 55 C8 B1 71 99 4D   53
C260 : 00 C0 02 D0 F6 A0 00 B1   33
C268 : 23 D1 4E F0 04 B0 0B 90   39
C270 : CF C8 C4 55 D0 F1 C4 22   73
C278 : B0 C6 A0 02 B1 6E AA B1   90
C280 : 71 91 6E 99 22 00 8A 91   F8
C288 : 71 88 10 F0 30 B2 18 A5   A4
C290 : 6E 69 03 85 6E 90 8F E6   9C
C298 : 6F D0 8B 60 AD 36 03 18   27
C2A0 : 69 09 85 22 85 24 AD 37   D2
C2A8 : 03 69 00 85 23 85 25 20   44
C2B0 : 01 C3 A6 B5 A5 24 18 6D   AA
C2B8 : 38 03 85 24 A5 25 6D 39   03
C2C0 : 03 85 25 CA D0 EE A0 00   2F
C2C8 : B1 22 AA B1 24 91 22 8A   D8
C2D0 : 91 24 C8 C0 03 D0 F1 A5   87
C2D8 : 22 C5 5C D0 07 A5 23 C5   C4
C2E0 : 5D D0 01 60 A5 22 18 69   90
C2E8 : 03 85 22 A5 23 69 00 85   74
C2F0 : 23 A5 24 18 69 03 85 24   FF
C2F8 : A5 25 69 00 85 25 4C C6   CA
C300 : C2 A5 22 18 6D 38 03 85   D0
C308 : 5C A5 23 6D 39 03 85 5D   2A
C310 : A5 5C 38 E9 03 B0 02 C6   7A
C318 : 5D 85 5C 60               B6
Listing 3. »Array-Sort«, eine schnelle Sortierroutine für String-Arrays.
(Franz Schinagl/tr)

SMON verbessert

Der Vergleichsbefehl des SMON läßt sich noch wesentlich optimieren: Dadurch bricht der SMON nicht bei dem ersten ungleichen Byte den Vergleich ab, sondern vergleicht solange, bis die Stop-Taste gedrückt wird.

Hierzu wird einfach aus dem »JMP $C323« bei Adresse »$CB0E« der Befehl »JSR $0323« gemacht. Zusätzlich müssen nur noch zwei Befehle in das SMON-Disassembler-Listing eingefügt werden. Daraus folgt, daß der SMON ab $CB11 um 6 Byte nach hinten verschoben werden muß und einige Speicherzellen ebenfalls geändert werden müssen.

Die zu ergänzenden 2 Befehle haben die Aufgabe, die Stop-Taste-Routine aufzurufen und den Vergleich weiterlaufen zu lassen.

Um dies möglichst einfach zu machen (Verschieben, Umrechnen und Einfügen von Befehlen), schildere ich nun die einfachste Methode.

  1. SMON $C000 laden und den Befehl NEW eingegeben.
  2. Reassembler laden, nach $9000 verschieben und »NEW« eingeben.
  3. Listing 4 eingeben und den Reassembler mit »SYS 36864, $C000, $CFEA : RUN« starten
  4. Das erhaltene Quelltextprogramm speichern (zirka 119 Blocks)
  5. Hypra-Ass laden und starten
  6. Das Quelltextprogramm mit /l"name" laden
  7. Listing 5 eintippen.
  8. Hypra-Ass starten.
  9. Wenn der Assembler fertig ist (nach 1 Minute), den neuen SMON starten und mit »S"NAME" C000 D000« speichern.

SMON nach $9000 verschieben:

  1. W C000 D000 9000
  2. V C000 D000 900 920B 9FD8
  3. M 902B 906B :Injedemzweiten Byte das erste »C« in eine »9« umwandeln
  4. FIC*,9000,9FFA :Die Befehle so umändern wie in der 64’er, Ausgabe 12/85 erwähnt. (Achtung: ab $9B00 stimmen die Adressen der Befehle mit den alten Adressen nicht mehr überein)
  5. M 9FDE 9FEA :Wie unter »3«.
100 ←t$c00b,$c213
110 ←t$cfd2,$cfe9
120 ←e32
Listing 4. Damit definieren Sie die Tabelle des SMON.
1350-          .by $3c,$ca,$5c,$c5,$16,$cb,$e2,$c3
1380-          .by $f6,$cb,$42,$ca,$d2,$c9,$6d,$c3
1390-          .by $09,$ce,$00,$00,$00,$00,$00,$00
12970-lxxxx    jsr lc367
13020-lcb0b    jsr lc351
13030-         jsr lc323
13031-         jsr lc486
13032-         jsr lxxxx
14300-         lda #$3c
14560-         lda #$58
15220-         lda #$76
16000-         lda #$9b
16370-         lda #$9b
17960-         lda #$f7
18400-tlcfd8   .by $78,$ce,$02,$cd,$02,$cd,$4e,$ce
18410-         .by $cb,$cf,$8b,$cf
Listing 5. Diese Zeilen müssen Sie zum Quelltext des SMON eintippen.
(Reinet Gebhardt/tr)
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →