Tips & Tricks für Anfänger und Fortgeschrittene
Wiedereinmal können wir Ihnen eine Auswahl aus unserer Tips & Tricks-Kiste anbieten. Für fast jeden Leser dürften einige interessante Programmiertricks dabei sein.
Primzahlen-Einzeiler
Bei folgendem Einzeiler handelt es sich um ein Programm zur Errechnung und Ausgabe aller Primzahlen bis 1000. Es benötigt hierfür zirka 27 Sekunden.
10DIMA(2000):FORI=2TO1000:IFA(I)=0THENPRINTI:FORJ=I+ITO1000STEPI:A(J)=1:NEXTJ,I:01100 NEXT
Der Einzeiler ist zu lang, um mit ausgeschriebenen Basic-Befehlen eingegeben werden zu können. Man muß ihn also wie folgt eingeben:
10DIMA(2000):FOI=2TO1000:IFA(I)=0TH?I:FOJ=I+ITO1000STEPI:A(J)=1:NEJ,I:01100 NE
Das Programm ist in dieser Form noch nicht lauffähig. Man muß erst noch einen Befehl im Direktmodus eingeben, nämlich: POKE2109,0
Das Programm kann jetzt mit »RUN« gestartet und mit »SAVE« gespeichert werden. Es arbeitet nach dem »Sieb des Eratosthenes«, bei dem die Vielfachen einer Primzahl aus einer Liste gestrichen werden.
Im Programm steht 01100. Die erste 0 wird durch den POKE-Befehl überschrieben, dadurch denkt der Computer, daß die Zeile nach dem NEXTJ,I zu Ende ist. Die 1100 sind Pseudo-Zeilennummer und Koppeladresse, dadurch springt der Computer, wenn die IF/THEN-Bedingung nicht erfüllt ist, nicht zur nächsten Zeile, sondern zum zweiten NEXT Sie können natürlich auch zwei oder drei Zeilen machen, um sich die Arbeit zu erleichtern.
(Michael Patra/tr)Etiketten drucken mit dem MPS-801
Durch folgende Änderungen läßt sich das Programm »ETIKETTEN 64« im 4. Sonderheft, Seite 15, das in der Originalversion für einen Commodore-Drucker 1526 (MPS-802) geschrieben worden ist, auch miteinem MPS-801 (1525) betreiben. Das Problem bestand lediglich darin, den fest eingestellten Zeilenabstand des MPS-801 auf Null zu reduzieren, denn sonst hat der Ausdruck nicht viel Ähnlichkeit mit der erstellten Etikette auf dem Bildschirm.
Zeile 6930 wird gelöscht
7040 IFA$<>"-"THENPRINT#3,CHR$(15);A$;CHR$(8);:GOTO 7080
7050 PRINT#3,CHR$(14):
7060 J=J+1:A$=MID$(T$,J,1)
7070 PRINT#3,A$;CHR$(15)CHR$(8);
Die eigentlichen Veränderungen stehen nur in den Zeilen 7040 und 7070.
CHR$(15): Einschalten Standardzeichen
CHR$(8) : Einschalten des Bit-Modus
Der Trick besteht darin, daß, wenn sich der Drucker im Bit-Modus befindet, ein Zeilenvorschub dazu führt, daß die folgende Zeile ohne Zeilenabstand gedruckt wird und so der standardmäßige zirka 3-Pixelabstand entfällt. Dieses Prinzip ist allgemein anwendbar, zum Beispiel wenn man ein Bild der Grafik (mit Commodore-Grafikzeichen), so wie auf dem Bildschirm zu sehen, zu Papier bringen will. Die PRINT-AT-Zeilen für den Drucker müssen dann folgendes Format haben: 1000 print #lf,chr$(15);"…."chr$(8) -lf=logische Filenummer des OPEN-Befehls.
(Karsten Bluhm/tr)Verbessertes PRINT USING mit Simons Basic
Die USE-Routine in Simons Basic vermag Zahlen mit einer definierten Anzahl an Vor- und Nachkommastellen auszugeben. So gibt zum Beispiel die Festlegung »USE " # # # #. # # # # #", STR$(A)« die Zahl A, die in einen String umgewandelt wird, mit vier Stellen vor und fünf Stellen hinter dem Dezimalpunkt aus. Im allgemeinen ein sehr nützlicher Befehl, wenn nicht folgender Nachteil auftreten würde:
Diese Förmatierungsroutine macht selbst vor Exponentialzahlen nicht Halt. So wird die Zahl 1.12345678E-05 mit der obigen Festlegung ausgegeben als "1.12345"! Sämtliche Dezimalen nach der fünften Stelle werden mitsamt dem Exponenten abgeschnitten! Selbstder Exponent wird wie Dezimalziffern nach dem Komma behandelt; es wird nicht nur die Mantisse formatiert!
Dieses Mißgeschick beseitigt die folgende Routine. Die zu formatierende Zahl wird als Variable A dem Unterprogramm übergeben. Das Unterprogramm ermittelt die Mantisse MA und den Zehnerexponenten EA der Zahl A.
50000 PROC FORMAT
50010 REM ZU FORMATIERENDE ZAHL : A
50030 LA=LOG(ABS(A))/LOG(10) : REM ZEHNERLOGARITHMUS
50040 EA=INT((LA*10+.5)/10) : REM ZEHNEREXPONENT
50050 MA=A/10tEA:REMMANTISSE
50100 END PROC
Aufgerufen wird die Routine mit »CALL FORMAT«. Die Mantisse MA und der Exponent EA können im Hauptprogramm an andere Variablen übergeben werden. Eine Möglichkeit wäre zum Beispiel bei vielen zu formatierenden Zahlen MA und EA in einem Feld (Matrix) zu speichern und nach Programmdurchlauf in einer Tabelle (mit Hilfe von USE) auszugeben.
Der Exponent EA der Zahl A kann in die wissenschaftliche Notation gebracht werden, in dem man ihn in ein Vielfaches von 3 umwandelt. Entsprechend muß die Mantisse MA umgerechnet werden (Multiplikation mit 10 beziehungsweise 100).
Dies geschieht wie folgt: Man dividiert EA durch 3 und erhält den Quotienten Q=EA/3. Der ganzzahlige Anteil (INT) mit 3 multipliziertergibtden neuen Exponenten: EA=INT(Q)*3; der rationale Anteil (FRAC) multipliziert mit 3 ergibt den Faktor für die Mantisse: F=FRAC(Q)*3: MA=MA*1EF.
Beispiel: EA=11, angestrebt: EA=-9.
Q=EA/3=-3.666666666,
EA=INT(Q)*3=-3*3=-9,
F=FRAC(Q)*3=.666666666*3 = 2,
MA=MA*1EF=MA*1E2 = MA*100.
Um Rundungsfehler zu vermeiden, sollte man bei der Berechnung des Faktors F auf ganzzahlige Werte runden (INT oder eigene Rundungsroutine, siehe weiter unten). Die Mantisse muß immer mindestens drei Stellen vor dem Komma besitzen, ein Vorzeichen und zwei Ziffern!
Um die Mantisse nicht einfach nach der kten Dezimalstelle abzuschneiden, sondern gerundet auszugeben, kann folgender Algorithmus verwendet werden: INT((MA*1EK+.5)/1EK).
Liegt der Exponent EA als Vielfaches von 3 vor, so kann bei Meßergebnissen die Vorsilbe der Einheit (Kilo, Milli, Piko, etc.) ermittelt werden. Die entsprechende Vorsilbe kann dann als V$ der Maßeinheit (M$) vorangestellt werden (V$+M$). Die möglichen Vorsilben mit den dazugehörigen Zehnerexponenten sind:
| Exa | E | 1018, | Atto | a | 10-18, |
| Peta | P | 1015, | Femto | f | 10-15, |
| Tera | T | 1012, | Pico | p | 10-12, |
| Giga | G | 109, | Nano | n | 10-9, |
| Mega | M | 106, | Mikro | μ | 10-6, |
| Kilo | k | 103, | Milli | m | 10-3, |
| Hekto | h | 102, | Zenti | c | 10-2, |
| Deka | d | 101, | Dezi | d | 10-1. |
Wie man sieht, sind die Potenzen zu den Vorsilben Hekto, Deka, Zenti und Dezi keine Vielfachen von 3. Diese können mit Hilfe eines IF-THEN-Statements ausgesondert werden.
IF ABS(EA)>2THEN EXEC VORSILBE,
wobei durch »VORSILBE« ein Unterprogramm aufgerufen wird, welches die Vorsilben zu den Exponenten, die Vielfache von 3 sind, ermittelt. Statt »EXEC« ist natürlich auch ein Sprung zu einer Marke (PROC…) mittels »CALL« möglich.
Hilfe für/gegen Turbo-Tape
Wenn sie mit Turbo-Tape geladen wurden, stürzen manche Programme, die den Speicher von 50000 bis 51000 benutzen, plötzlich ab. Das liegt daran, daß Turbo-Tape den Vektor zum Holen eines Befehls auf eine eigene Routine richtet. Wird nun diese Routine überschrieben, steigt der Computer wenn er den nächsten (Basic-)Befehl sucht, aus, da das Programm, auf das der Vektor $308 zeigt, nicht mehr existiert. Die Veränderung dieses Vektors ist von Basic aus nicht möglich, aber durch »SYS 58451« (Standard Basic Vektoren $0300 bis $030B laden) wird er wieder »geradegebogen«.
(Julian Ziersch/tr)INPUT ohne Fragezeichen
Das manchmal lästige Fragezeichen beim Basic-Befehl »INPUT« kann man durch ein »POKE 19,1« verschwinden lassen. Allerdings sollte diese Manipulation sofort nach der INPUT-Anweisung durch »POKE 19,0« wieder rückgängig gemacht werden.
(Günther Stangl/tr)Schachuhr
2 S=1—S:TI$=A$(S):FORI=1TO1:GETI:A$(S)=TI$:PRINT" {CLR,3SPACE}?"A$(1),„A$(0):IFA$(S) < E$THENNEXT: GOTO2
Nachdem ich für ein Schachuhrprogramm eine Bildschirmseite verbraucht hatte, beschloß ich, dreses Programm ordentlich zu kürzen. Schließlich wurde es dann zu dem vorliegenden Einzeiler, der aus Ihrem Computer eine richtige Schachuhr macht.
A$(0)="000000":A$(1)="000000":E$="000020": PRINT"{CLR}":GOTO 2
Zuerst müssen die Anfangszeiten der beiden Spieler definiert werden, die wohl jeweils Null sein dürften, wenn man nicht gerade gegen einen weitaus stärkeren Spieler spielt. (Jeweils A$(0) und A$C(1) im bekannten sechsstelligen Format der internen Uhr TI$). Danach definiert man die Endzeit E$ (wie oben), bei der das Programm stoppen soll und startet den Einzeiler nach einem SHIFT/CLR-HOME mit GOTO2 (nicht mit RUN, um die Stringvariablen nicht zu löschen).
Auf Druck der Zahlen 1-9 läuft jeweils die Uhr des Gegenspielers weiter. Will man eine Pause machen, drückt man irgendeinen Buchstaben.
Mit GOTO 2 kann das Programm dann fortgesetzt werden (ohne sich an dem »Syntax Error« zu stören), worauf die jeweils andere Uhr, als die, die vor Abbruch lief, weiterläuft.
Zur Erklärung des Einzeilers
S=1—S« ändert S jeweils von 0 auf 1 oder von 1 auf 0 (es läuft dann jeweils die Uhr von Spieler 1 oder 0). Nun wird die Uhr TI$ gestellt. Danach folgt eine For-Next-Schleife, die nur verlassen werden kann, wenn I eine der Zahlen von 1-9 annimmt, was nur bei Drücken irgendeiner Zahl geschehen kann. Sonst ist I durch die »GETI«-Abfrage immer Null. In der Schleife wird die jeweilige Zeit der beiden Spieler ausgegeben. Außerdem wird untersucht, ob die Endzeit erreicht ist.
(Oliver Stengelin/tr)Der Hypra-Listschutz
Ich habe schon öfters im Leserforum gelesen, daß bei Aktivierung des Befehls »POKE 808,225« ein verstümmeltes Listing erscheint. Ich habe da eine Lösung gefunden: Nach Eingabe der Zahlenkombination 35072120 ist das Listing wieder normal sichtbar. Unglaublich, aber wahr!
Hier nun unsere Preisfrage an die Profis:
Was geschieht hier?
Der erste Leser, der uns die richtige Lösung schickt, bekommt einen 64’er-Aufkleber!
(Helmut Skolaut/tr)Maschinenprogramme kopieren
Wenn man nicht zu den glücklichen Besitzern eines Kopierprogramms gehört, kann man Maschinenprogramme mit Hilfe des MSE kopieren: M8E laden — M8E starten — Programm laden — andere Diskette/Kassette einlegen — Programm mit CTRL-S wieder speichern. Basic-Programme lassen sich mit dieser Methode übrigens genauso kopieren.
(tr)Geräusche von A bis Z
Durch Veränderung der Filterfrequenz und durch verschiedene Filter lassen sich einfache Geräusche erzeugen.
Zeile 10 S=54272:Rem Basisregister
Zeile 20 FORL=OTO24:POKES+L,0:NEXT
Zum Beispiel:
Um einen Schuß zu erzeugen, muß das Programm wie folgt aussehen:
10 S=54272
20 FORL=OTO24:POKE S + L,0: NEXT
30 POKE S + 0,0 : POKE S + 1,18
40 POKE S + 5,1 * 16 + 11
50 POKES + 22,110
60 POKE S + 23, 15 * 16 + 3
70 POKE S + 24, 5 * 16 + 15
80 POKE S + 4, 0 : POKE S + 4, 129
90 FORJ = 1 TO 255 : POKE S + 0,J : NEXT
100 FORA = 1 T 1000 : NEXT : GOTO 80
| Zeile 30 | Zeile 40 | Zeile 50 | Zeile 60 | Zeile 70 | Zeile 80 | Zeile 90 | Zeile 100 | |
| Geräusch: | Frequenz | Hall | Grenzfre- quenz |
Resonanz | Pass | Wellenform | Schleife und POKE |
Warteschleife und GOTO |
| Schuß | POKE S+0,0: POKE S+1,18 |
POKE S+5,1*16+ 11 |
POKE S+22,110 |
POKE S+23,15*16 +3 |
POKE S+24,5*16 +15 |
POKE S+4,0: POKE S+4,129 |
FORJ=1TO 255: POKE S+0,J: NEXT |
FORA=1TO 1000: NEXT:GOTO80 |
| Explosion | POKE S+0,0: POKE S+1,6 |
POKE S+5,2*16+ 13 |
POKE S+22,100 |
POKE S+23,15*16 +3 |
POKE S+24,3*16 +15 |
POKE S+4,0: POKE S+4,129 |
FORJ=1TO 100: POKE S+0,J: NEXT |
FORA=1TO 4000: NEXT:GOTO80 |
| Uhrenschlag | POKE S+0,0: POKE S+1,6 |
POKE S+5,1*16+ 10 |
POKE S+22,110 |
POKE S+23,15*16 +3 |
POKE S+24,1*16+ 15 |
POKE S+4,0: POKE S+4,17 |
FORJ=1TO 255: POKE S+0,7: NEXT |
FORA=1TO 500: NEXT:GOTO80 |
| Brandung | POKE S+0,0: POKE S+1,40 |
POKE S+5,10*16+ 12 |
POKE S+22,0 |
POKE S+23,0 |
POKE S+24,0*16 +15 |
POKE S+4,0: POKE S+4,129 |
FORJ=1TO 255: POKE S+0,J: NEXT |
FORA=1TO 3500: NEXT:GOTO80 |
POKE oder nicht POKE
Vielleicht ist manchen Computer-Fans, die öfters an unterschiedlichen C 64 arbeiten, schon folgendes aufgefallen: Bei einigen älteren Modellen bewirkt ein »POKE 1024,1« überhaupt nichts, bei den neueren hingegen erscheint in der oberen linken Bildschirmecke ein »A«. Warum erscheint bei den älteren Modellen das »A« nicht auf dem Bildschirm, obwohl doch alles korrekt gemacht wurde? Das liegt daran, daß das alte Betriebssystem des C 64 die Zeichen nicht in der Zeichen-, sondern in der Hintergrundfarbe in den Bildschirm schreibt Sie sind also zwar vorhanden, aber nicht sichtbar. Dies werden sie erst, wenn durch einen entsprechenden Eintrag in den Farbspeicher ab Adresse 55296 die Farbe des Zeichens extra gesetzt wird. In unserem Fall mit dem »POKE 1024,1« müßte also noch ein »POKE 55296,14« (für ein hellblaues »A«) folgen. Deswegen sollten auch Besitzer eines neueren C 64, die uns Listings schicken, diese Farb-POKEs hinzufügen. Die Programme könnten sonst auf den älteren Computern merkwürdige Bildschirmdarstellungen haben. Für Besitzer eines EPROM-Brenners, die sich ein neues Kernel brennen wollen, sei noch kurz angemerkt, wie das Kernel »richtig« lauten muß, um den Farb-POKE automatisch zu setzen:
alt: $E4DA LDA $D021 (=Zeichen in Hintergrundfarbe)
neu: $E4DA LDA $0286 (=Zeichen in Zeichenfarbe)
?VERIFY ERROR
Da hat man ein gutes Basic-Programm geschrieben, und dann tritt beim obligatorischen VERIFY dieser Fehler auf. Aber in welcher Programmzeile steckt der Fehler? Dieses Programm (Listing 1) gibt die fehlerhafte Zeilen-Nummer an. Beide Programme müssen auf einer Diskette sein.
Folgende Fehleraussagen sind möglich:
- Ungleiche Zeilenlänge
- Zeichenfehler bei gleicher Zeilenlänge (oder ein Basic-Befehl ist anders)
- Ungleiche Zeilennummer
- Fehlen einer Zeile
Bei Fehlen einer Zeile beziehungsweise ungleicher Zeilennummer wird der Vergleich mit der Aussage »Bitte überprüfen« abgebrochen.
(Gerhard Reul/tr)1 rem vergl.von prg.
10 :
20 rem *************************
30 rem * *
40 rem * gerhard reul *
50 rem * 8591 troestau *
60 rem * tel. 09232/1678 *
70 rem * *
80 rem *************************
90 :
100 dim x(256),y(256):z1$="......"
110 f1$="<> zeilen-laenge":f2$="zeichen-fehler":f3$="<> zeilen-nr.!!!"
120 goto450
130 open15,8,15,"i"
140 open2,8,2,b1$+",p,r":f=1:gosub590
150 open3,8,3,b2$+",p,r":f=2:gosub590
160 get#2,x$,x$
170 get#3,x$,x$
180 rem======= laden prg 1 =============
190 get#2,x$:ifx$=""thenx$=chr$(0)
200 i=i+1:x(i)=asc(x$)
210 rem (zu zeile 220) zeilen-nr. bestimmen
220 ifi=4thenz=x(4)*256+x(3):z$=right$(z1$+str$(z),7):print" zeile"z$" ok{up}"
230 ifx(i)=0then goto260
240 goto190
250 rem zeilen-oder prg.-ende bestimmen
260 ifi=2then:ifx(1)=0andx(2)=0thenclose2:close3:close15:goto550:rem prg.-ende
270 ifi<5thengoto190
280 ii=i:i=0
290 rem======= laden prg 2 =============
300 get#3,y$:ify$=""theny$=chr$(0)
310 j=j+1:y(j)=asc(y$)
320 ify(j)=0then goto340
330 goto300
340 ifj<5thengoto300
350 jj=j:j=0
360 rem====== vergleichen ==============
370 ifx(3)<>y(3)orx(4)<>y(4)then:f$=f3$:gosub420:goto430
380 ifii<>jjthen:f$=f1$:gosub420:goto190
390 fori=5toii
400 ifx(i)<>y(i)then:f$=f2$:gosub420:i=ii
410 next:i=0:goto190
420 print"{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}"f$:return
430 print"{down} {rvon} bitte ueberpruefen ! {rvof}":close2:close3:close15:goto560
440 rem========= menue =================
450 print"{clr}{down}{down} {rvon} vergleichen von programmen {rvof}{down}{down}"
460 print" es koennen zwei basic-programme,{down}"
470 print" die sich auf einer diskette befinden,{down}"
480 print" miteinander verglichen werden.{down}{down}{down}{down}"
490 input" programm-name 1 ";b1$:print:print
500 input" programm-name 2 ";b2$
510 print"{clr}{down}{down} {rvon} vergleichen von programmen {rvof}{down}{down}"
520 print" programm 1: programm 2:{down}{down}"
530 print" "b1$" "b2$"{down}{down}":goto130
540 rem========== warten ===============
550 print"{down}{down} {rvon} ende {rvon}"
560 geta$:ifa$=""then560
570 run
580 rem====== fehler-kanal =============
590 input#15,a,a$:ifa=0thenreturn
600 print" "f"{left}. ";a$:close2:close3:close15
610 goto560
INT-Funktion fehlerhaft
Wie mir neulich auffiel, ist die »INT<-Funktion beim C 64 keineswegs die definitionsgemäße Integer-Funktion, wie man aus der Abkürzung entnehmen könnte, sondern die Gaussklammerfunktion. Glücklicherweise ist die Funktion im Handbuch richtig erklärt, nur stimmt nicht, daß »negative Zahlen dem Betrag nach größer werden«, wenn man die Nachkommastellen abschneidet. Die im Betriebssystem definierte Funktion rundet alle Zahlen ab, anstatt die Nachkommastellen abzuschneiden. Das heißt: f(x) = [x] (Gaussklammer), und nicht: f(x) = [ixi] • sgn(x)(lnteger).AuslNT(—1.23)wirdnämlich—2 und nicht, wie es richtig heißen müßte, —1! Es ist also Vorsicht geboten bei Programmen oder Rechnungen, die die Integer-Funktion verlangen und bei denen x negativ ist. Bei kaufmännischen oder sonstigen Anwendungen des C 64, von denen nicht nur das Erfolgserlebnis des Programmierers abhängt, wäre es nötig, die Funktion im Programm neu zu definieren:
DEF FN INT(x) = INT (ABS(x)) * SGN(x)
(Matthias Möller/tr)Software-Hex-Tastatur
Das Programm (Listing 2) wird normal geladen und mit »RUN« gestartet. Es kopiert dann mit der schon im 64’er, Ausgabe 3/85, Seite 68 vorgestellten ROM-Routine das KernelROM in das darunterliegende RAM (Zeilen 30 bis 40) und verändert dort die Tastatur-Decodiertabellen (Zeilen 50 bis 70). Wenn sich der Computer wieder mit »READY.« meldet (nach zirka 0,5 Sekunden), lädt man wie gewohnt den MSE, gibt »POKE 2096,53« ein und startet ihn mit »RUN«. Durch die Änderung der Speicherstelle 2096 wird beim MSE-Start der Wert 53 in die Speicherstelle 1 der Zeropage geschrieben. Deshalb holt sich der Computer seine Informationen im Kernel-Bereich nicht mehr aus dem ROM, sondern aus dem RAM, wo die geänderte Tastaturdecodiertabelle steht. Die neue Tastenbelegung wird wie folgt aktiviert: Die normalen Funktionen bleiben bestehen, mit »Shift« ergeben sich aber folgende Umbelegungen:
- auf M bis / liegen 0 bis 3
- auf K bis ; liegen 4 bis 7
- auf I bis @ liegen 8 bis B
- auf 9 bis — liegen C bis F.
Auch die Belegung der INST-DEL-Taste wurde verändert (Zeile 70): ohne Shift wird jetzt INST, mit Shift DEL ausgeführt. Es empfiehlt sich also, bei der Eingabe von MSE-Programmen die Shift-Lock-Taste zu drücken und dann mit den neuen Tasten zu arbeiten. Als Merkhilfe kann man seitlich auf die Tasten kleine Aufkleber mit der neuen Belegung kleben.
(Sven Heemeyer/Andreas Meyer/tr)10 rem mse-hex-tastatur
20 rem von s. heemeyer & a. meyer
30 s=820:fori=stos+6:reada:pokei,a:nexti
40 poke88,0:poke89,0:poke90,0:poke91,0:poke780,0:poke781,224:syss
50 fori=48to57:reada:poke60354+a,i:next
60 fori=65to70:reada:poke60354+a,i:next
70 poke60289,148:poke60354,20
80 print"{clr}mse laden, dann poke2096,53:run"
90 data133,95,134,96,76,191,163
100 data36,47,44,55,37,42,45,50,33,38
110 data41,46,32,35,40,43
Die unmögliche Uhr
Dieses Programm stellt während des Editierens oder Ablaufs von Basic- oder Maschinenspracheprogrammen im unteren Rand des Bildschirms eine absolut genaue Uhr mit Stunden-, Minuten und Sekundenanzeige dar. Es verbraucht keinen Basic-Speicherplatz, da das Steuerprogramm von $C000 bis $C2D7 und die Spritedaten unter dem KernelROM liegen. Es verfügt über einen minutengenau einstellbaren Wecker. Zur Funktionsweise des Programmes:
Der VIC II-Chip wird in der IRQ-Routine veranlaßt, an zwei Bildschirmstellen einen Interrupt auszulösen. Die erste dieser Stellen liegt am unteren Bildschirmrand. Hier wird durch Ändern der Speicherstelle 53265 der Bildschirm »verlängert«. Da die Uhr unabhängig von Programmen laufen soll, in denen auch Sprites vorkommen, werden die aktuellen Spritedaten gerettet und erst dann die Daten für die Uhr in die entsprechenden VIC-Register geschrieben. Zusätzlich wird die Bank-select-Speicherstelle 56576 »umgeschaltet«, um die Uhr-Sprite-Daten unter dem Kernel-ROM lesen zu können. Anschließend werden die Spritezeiger nach der exakten, weil durch Netzfrequenz getakteten Tageszeituhr des CIA 2-Chip korrigiert und bei Erreichen der Alarmzeit ein optisches und akustisches Signal ausgegeben.
Die zweite Bildschirmstelle, an der ein Interrupt ausgelöst wird, liegt im unteren, nicht mehr sichtbaren Bildschirmbereich. Hier erhalten die VIC-Register und die Bank-select-Speicherstelle wieder ihre ursprünglichen Werte.
Nun zur Bedienung des Programms:
Nachdem Sie das Listing 3, »BORDER-CLOCK«, das Sie mit dem MSE abgetippt und gespeichert, gestartet haben, erzeugt dieses erst das eigentliche Programm »UHR« auf der Diskette. Dies hat folgenden Grund: Das endgültige Programm »UHR« enthält die vollständigen Daten für die Sprite-Ziffern 0 bis 9 und den Doppelpunkt. Diese Daten werden in »BORDERCLOCK« erst aus den sieben Segmenten einer Digital-Uhr zusammengesetzt. Dies bewirkt, daß »BORDER-CLOCK« etwa 200 Byte kürzer ist als »UHR«. Nach dem Laden und Starten des »UHR«-Programms müssen Zeit und Weckzeit in TI$-Schreibweise (je zwei Stellen für Stunden, Minuten und Sekunden) eingegeben werden.
Nach Drücken von RUN/STOP-RESTORE muß die Anzeige mit»SYS 49756« neu aktiviert werden, die Uhr läuft jedoch intern weiter. Vor der Arbeit mit Peripheriegeräten (Floppy, Drucker, etc.) muß die Anzeige ausgeschaltet werden. Dies kann durch die Tastenkombination CTRL-RESTORE erfolgen. Danach kann sie durch Commodore-Taste und RESTORE wieder eingeschaltet werden. Am Programm können Sie natürlich selbst einiges verändern.
Die Sprite-Daten der Ziffern 0 bis 9 und des Doppelpunktes liegen von 3270 bis 3974. Die Farbe des Uhrenhintergrundes ist in 2974 enthalten, die Farben der einzelnen Sprites von 2980 bis einschließlich 2987. Es können auch einzelne Ziffern ausgeschaltet bleiben, und zwar durch POKE 2962, PEEK(2962)AND(255-2↑1), wobei I zwischen 0 und 7 die auszuschaltende Stelle angibt. Schließlich kann noch die Frequenz des Alarmgongs mittels POKE 3072,INT(F/256): POKE 3067,F-256*PEEK(3072) mit F als Frequenz geändert werden.
(Anton Ernst/tr)PROGRAMM : B-CLOCK-HEFT 0801 0EFB ----------------------------------- 0801 : 26 08 0A 00 9F 32 2C 38 5B 0809 : 2C 32 2C 22 40 30 3A 55 B7 0811 : 48 52 2C 50 2C 57 22 3A 12 0819 : 98 32 2C C7 28 31 29 C7 0F 0821 : 28 38 29 3B 00 47 08 14 9A 0829 : 00 81 49 B2 30 A4 31 32 E4 0831 : 32 30 3A 98 32 2C C7 28 11 0839 : C2 28 32 34 30 36 AA 49 14 0841 : 29 29 3B 3A 82 00 5A 08 B7 0849 : 64 00 47 B2 33 37 30 34 EC 0851 : 3A 86 46 28 38 30 30 29 7D 0859 : 00 98 08 6E 00 81 49 B2 0C 0861 : 30 A4 36 3A 81 59 B2 31 C8 0869 : A4 C2 28 33 36 39 37 AA 3E 0871 : 49 29 3A 42 28 49 2C 59 56 0879 : 29 B2 C2 28 47 29 3A 47 E6 0881 : B2 47 AA 31 3A 57 28 49 39 0889 : 2C 59 29 B2 C2 28 47 29 DF 0891 : 3A 47 B2 47 AA 31 00 BE B6 0899 : 08 78 00 82 59 2C 49 3A BE 08A1 : 81 58 B2 30 A4 39 3A 81 01 08A9 : 59 B2 30 A4 36 3A 81 5A EC 08B1 : B2 31 A4 C2 28 33 36 39 E5 08B9 : 37 AA 59 29 00 F2 08 82 7E 08C1 : 00 8B C2 28 33 36 32 37 59 08C9 : AA 37 AC 58 AA 59 29 B2 C4 08D1 : 31 A7 41 B2 42 28 59 2C A0 08D9 : 5A 29 AA 58 AC 36 34 3A 3F 08E1 : 46 28 41 29 B2 46 28 41 31 08E9 : 29 B0 57 28 59 2C 5A 29 F8 08F1 : 00 18 09 8C 00 82 5A 2C A7 08F9 : 59 2C 58 3A 81 49 B2 30 53 0901 : A4 31 31 AC 36 34 3A 97 3D 0909 : 35 37 33 34 34 AA 49 2C 43 0911 : 46 28 49 29 3A 82 00 44 23 0919 : 09 96 00 41 B2 36 30 3A A8 0921 : 81 49 B2 30 A4 32 3A 46 4B 0929 : 28 36 35 39 AA 33 AC 49 6A 0931 : 29 B2 41 3A 46 28 36 37 38 0939 : 34 AA 33 AC 49 29 B2 41 50 0941 : 3A 82 00 64 09 A0 00 81 E2 0949 : 49 B2 30 A4 31 31 AC 36 48 0951 : 34 3A 98 32 2C C7 28 46 3D 0959 : 28 49 29 29 3B 3A 82 3A 99 0961 : A0 32 00 00 00 1A 08 0A 20 0969 : 00 97 20 35 33 32 38 30 EA 0971 : 2C 30 32 3A 97 20 35 33 3F 0979 : 32 38 31 2C 32 00 46 08 E6 0981 : 14 00 99 22 93 11 11 11 68 0989 : 1D 9E 55 48 52 5A 45 49 F3 0991 : 54 3A 20 20 20 20 05 22 6A 0999 : 3B 3A 9F 31 2C 30 2C 30 55 09A1 : 3A 84 31 2C 54 24 3A A0 80 09A9 : 31 00 76 08 1E 00 99 C7 51 09B1 : 28 31 33 29 20 22 11 11 DD 09B9 : 1D 9B 57 45 43 4B 5A 45 A5 09C1 : 49 54 3A 20 20 20 05 22 22 09C9 : 3B 3A 9F 31 2C 30 2C 30 85 09D1 : 3A 84 31 2C 57 24 3A A0 E0 09D9 : 31 00 9D 08 28 00 48 24 5F 09E1 : B2 C8 28 54 24 2C 32 29 4B 09E9 : 3A 4D 24 B2 CA 28 54 24 B1 09F1 : 2C 33 2C 32 29 3A 53 24 02 09F9 : B2 C9 28 54 24 2C 32 29 E3 0A01 : 00 C7 08 32 00 42 B2 30 6A 0A09 : 3A 8B C5 28 48 24 29 B1 2D 0A11 : 31 32 A7 42 B2 31 3A 48 BC 0A19 : 24 B2 C9 28 C4 28 C5 28 03 0A21 : 48 24 29 AB 31 32 29 2C DD 0A29 : 32 29 00 D9 08 3C 00 8B A5 0A31 : 20 48 24 B2 22 30 30 22 7D 0A39 : A7 42 B2 31 00 04 09 46 A5 0A41 : 00 97 20 35 36 35 38 37 18 0A49 : 2C 31 36 AC C5 28 C8 28 42 0A51 : 48 24 2C 31 29 29 AA C5 EF 0A59 : 28 C9 28 48 24 2C 31 29 34 0A61 : 29 B0 42 AC 31 32 38 00 8E 0A69 : 29 09 50 00 97 20 35 36 E7 0A71 : 35 38 36 2C 31 36 AC C5 D8 0A79 : 28 C8 28 4D 24 2C 31 29 74 0A81 : 29 AA C5 28 C9 28 4D 24 D1 0A89 : 2C 31 29 29 00 4E 09 5A 09 0A91 : 00 97 20 35 36 35 38 35 64 0A99 : 2C 31 36 AC C5 28 C8 28 92 0AA1 : 53 24 2C 31 29 29 AA C5 4A 0AA9 : 28 C9 28 53 24 2C 31 29 E5 0AB1 : 29 00 7A 09 64 00 81 20 27 0AB9 : 49 B2 30 20 A4 20 33 3A F8 0AC1 : 97 35 31 31 30 30 AA 49 27 0AC9 : 2C C5 28 CA 28 57 24 2C 61 0AD1 : 49 AA 31 2C 31 29 29 AA 98 0AD9 : 31 32 38 3A 82 00 8F 09 F1 0AE1 : 6E 00 97 20 35 36 35 38 84 0AE9 : 34 2C 30 3A 99 22 11 11 98 0AF1 : 11 22 00 9A 09 78 00 9E F8 0AF9 : 20 32 34 36 30 00 00 00 09 0B01 : A9 EF 85 AE A9 09 85 AF 31 0B09 : A9 00 85 B0 A9 C0 85 B1 44 0B11 : A0 00 B1 AE 91 B0 E6 AE 8B 0B19 : D0 02 E6 AF E6 B0 D0 02 D5 0B21 : E6 B1 A5 B1 C9 C3 D0 EA 53 0B29 : A9 C6 85 AE A9 0C 85 AF DD 0B31 : A9 00 85 B0 A9 E0 85 B1 6D 0B39 : A0 00 B1 AE 91 B0 E6 AE B3 0B41 : D0 02 E6 AF E6 B0 D0 02 FD 0B49 : E6 B1 A5 B1 C9 E5 D0 EA 8C 0B51 : 4C 5C C2 78 A9 7F 8D 0D 72 0B59 : DC A9 2C 8D 14 03 A9 C0 48 0B61 : 8D 15 03 A9 01 8D 1A D0 F5 0B69 : A9 F7 8D 12 D0 A2 2F BD 0E 0B71 : 00 D0 9D 5C C1 CA 10 F7 6F 0B79 : A9 00 8D 08 DD 58 60 78 9A 0B81 : AD 19 D0 8D 19 D0 AD 12 94 0B89 : D0 C9 F7 D0 2F A2 18 BD 3A 0B91 : 00 D0 9D 5C C1 BD 8E C1 B4 0B99 : 9D 00 D0 CA 10 F1 A9 C4 84 0BA1 : 8D 00 DD A9 00 8D 12 D0 31 0BA9 : A2 13 BD 1B D0 9D 77 C1 03 0BB1 : BD A9 C1 9D 1B D0 CA 10 EA 0BB9 : F1 4C 90 C0 20 CA C1 A2 B1 0BC1 : 18 BD 5C C1 9D 00 D0 CA BA 0BC9 : 10 F7 A9 F7 8D 12 D0 A2 30 0BD1 : 13 BD 77 C1 9D 1B D0 CA 64 0BD9 : 10 F7 A9 97 8D 00 DD 58 43 0BE1 : 4C 31 EA EA A0 00 AD 0B B5 0BE9 : DD 29 10 18 4A 4A 4A 4A 17 0BF1 : 69 80 48 AD 0B DD C9 12 4D 0BF9 : D0 09 A9 80 8D F8 C7 68 59 0C01 : 4C C1 C0 C9 92 D0 09 A9 BE 0C09 : 81 8D F8 C7 68 4C C1 C0 F9 0C11 : 68 8D F8 C7 AD 0B DD 29 74 0C19 : 0F 69 80 48 AD 0B DD C9 44 0C21 : 12 D0 09 A9 80 8D F9 C7 FF 0C29 : 68 4C EA C0 C9 92 D0 09 10 0C31 : A9 82 8D F9 C7 68 4C EA 85 0C39 : C0 68 20 32 C1 A9 8A 8D 2A 0C41 : FA C7 AD 0A DD 29 F0 4A 4B 0C49 : 4A 4A 4A 69 80 8D FB C7 6C 0C51 : AD 0A DD 29 0F 69 80 8D F9 0C59 : FC C7 A9 8A 8D FD C7 AD 38 0C61 : 09 DD 29 F0 4A 4A 4A 4A 76 0C69 : 69 80 8D FE C7 AD 09 DD 1F 0C71 : 29 0F 69 80 8D FF C7 AD DF 0C79 : 0E DD 09 80 8D 0E DD AD E4 0C81 : 08 DD 4C 57 C1 8D F9 C7 76 0C89 : AD 0B DD E9 80 10 01 60 BE 0C91 : EE F8 C7 EE F9 C7 EE F9 58 0C99 : C7 AD F9 C7 E9 8A 10 01 E3 0CA1 : 60 69 7F 8D F9 C7 EE F8 D3 0CA9 : C7 60 4C DA C1 32 60 00 3E 0CB1 : 00 00 00 00 00 00 00 00 B2 0CB9 : 00 00 00 00 00 00 00 00 BA 0CC1 : 1B FA D1 00 00 C8 00 15 3E 0CC9 : F9 F1 00 00 00 00 00 FA B1 0CD1 : F2 F1 F2 F3 F4 F0 F1 F2 7B 0CD9 : F3 F4 F5 F6 F7 FC FF EA E0 0CE1 : EA 32 0B 55 0B 73 0B 91 ED 0CE9 : 0B B4 0B D2 0B F0 0B 14 F8 0CF1 : 0B 80 17 59 9A 36 FF C8 1A 0CF9 : 00 15 79 F0 FF 00 00 00 00 0D01 : 00 FA 0C F1 F2 F3 F4 F0 44 0D09 : 01 01 01 01 01 01 01 01 09 0D11 : 02 FF 07 A2 18 BD 00 D0 3A 0D19 : DD 8E C1 D0 06 CA 10 F5 AB 0D21 : 60 EA EA E0 11 F0 F6 9D 7D 0D29 : 5C C1 4C 66 C1 AD 7C C1 45 0D31 : 8D AE C1 A2 01 BD 9C C7 DA 0D39 : DD F8 C7 D0 12 BD 9E C7 B7 0D41 : DD FB C7 D0 0A 4C CB C2 DF 0D49 : AD 88 C7 C9 0A 10 03 4C 2B 0D51 : 81 EA AD 87 C7 C9 D3 F0 A0 0D59 : 2D A9 0F 8D 18 D4 A9 00 9F 0D61 : 8D 00 D4 A9 0C 8D 01 D4 33 0D69 : A9 0C 8D 05 D4 A9 00 8D D2 0D71 : 06 D4 A9 11 8D 04 D4 A9 0D 0D79 : D3 8D 87 C7 A9 00 8D 7E BB 0D81 : C7 A9 28 8D 7F C7 A9 00 B5 0D89 : 8D 88 C7 EE 89 C7 AD 89 CB 0D91 : C7 C9 05 D0 17 A9 00 8D 72 0D99 : 04 D4 A9 11 8D 04 D4 A9 33 0DA1 : 00 8D 89 C7 AD AF C1 49 B5 0DA9 : 08 8D AF C1 4C 81 EA 20 59 0DB1 : 00 C0 A9 88 8D 18 03 A9 86 0DB9 : C2 8D 19 03 A9 00 8D FF B9 0DC1 : 3F 8D FF FF 8D 87 C7 8D 16 0DC9 : 88 C7 4C 85 C2 4B 52 4F 67 0DD1 : 57 20 4B 43 4F 4C 43 0D F2 0DD9 : 4C 83 A4 08 48 8A 48 98 3C 0DE1 : 48 AD 8D 02 C9 02 D0 0D AD 0DE9 : A9 2C 8D 14 03 A9 C0 8D 2A 0DF1 : 15 03 4C B0 C2 C9 04 D0 DD 0DF9 : 0A A9 B9 8D 14 03 A9 C2 7D 0E01 : 8D 15 03 68 A8 68 AA 68 30 0E09 : 28 4C 47 FE 78 AD 19 D0 04 0E11 : 8D 19 D0 AD 12 D0 F0 03 86 0E19 : 4C 31 EA 4C 81 EA CA 10 FD 0E21 : 06 EE 88 C7 4C F5 C1 4C CD 0E29 : E2 C1 01 01 01 00 01 01 62 0E31 : 01 00 00 01 00 00 01 00 57 0E39 : 01 00 01 01 01 00 01 01 B1 0E41 : 00 01 01 00 01 01 00 01 1C 0E49 : 01 01 00 01 00 01 01 00 F7 0E51 : 01 00 01 01 01 01 00 01 CD 0E59 : 01 01 01 01 00 01 00 00 43 0E61 : 01 00 01 01 01 01 01 01 E1 0E69 : 01 01 01 01 01 00 01 01 61 0E71 : 09 0A 0A 09 09 09 09 00 20 0E79 : 3F 01 FF 02 FC 03 1F 04 E5 0E81 : FF 05 F8 06 0F 07 FF 08 3B 0E89 : F0 00 80 03 C0 06 E0 09 CC 0E91 : E0 0C E0 0F E0 12 E0 15 DE 0E99 : E0 18 C0 1B 80 02 01 05 3F 0EA1 : 03 08 07 0B 07 0E 07 11 EB 0EA9 : 07 14 07 17 07 1A 03 1D E7 0EB1 : 01 1B 3F 1C FF 1D FC 1E AC 0EB9 : 7F 1F FF 20 FE 21 3F 22 06 0EC1 : FF 23 FC 21 80 24 C0 27 30 0EC9 : E0 2A E0 2D E0 30 E0 33 16 0ED1 : E0 36 C0 39 80 23 01 26 95 0ED9 : 03 29 07 2C 07 2F 07 32 23 0EE1 : 07 35 07 38 03 3B 01 33 C0 0EE9 : 0F 34 FF 35 F0 36 1F 37 64 0EF1 : FF 38 F8 39 3F 3A FF 3B AE 0EF9 : FC 42 61
Das 64’er EPROM-Programmiergerät
In der Testphase unseres Programmiergerätes haben sich zwei Veränderungen am Schaltplan des 64’er EPROM-Programmiergerätes ergeben (Ausgabe 12/85, Seite 47, Bild 5).
- Auf der PGM-Leitung muß ein 7404-Inverter zwischengeschaltet werden.
- Die vom 74LS139 (Pin 7) ausgehende Leitung muß zwischen dem Treiber und dem Invertierer abgezweigt und über eine Diode (1N4148) mit der Leitung zum Umschalter verbunden werden.
EPROM-Trans
Ausgabe 10/85, Seite 45, Bild 4
Bei der Zusatzplatine müssen die beiden ICs 74LS00 und 74LS04 vertauscht werden. Taster T1 und T2 müssen noch mit zwei Widerständen (1k5) bestückt werden (siehe Bild).

Der Riesen-Bildschirm
Dieses Hilfsprogramm (Listing 4) können Sie beim Schreiben eigener Programme verwenden, um Sprites auch über den oberen und unteren Rand hinaus zu bewegen. Das Programm kann von Basic oder Maschinensprache aus benutzt werden, da es im Kassettenpuffer von dezimal 828 bis 929 liegt und so den freien Speicherbereich nicht einschränkt. Die Funktionsweise des Programms:
Der VIC II-Chip löst an drei Bildschirmstellen einen Interrupt aus. Die erste liegt am unteren Bildschirmrand, hier wird durch einen Programmiertrick der Bildschirm »verlängert«. Die zweite Stelle liegt sieben Rasterzeilen unterhalb der ersten. Hier wird durch Auswertung der Speicherstelle 931 entschieden, ob und welche Sprites im unteren Randbereich sichtbar sein sollen. Die dritte Stelle liegt im unteren, nicht mehr sichtbaren Bildbereich, wo abhängig vom Inhalt der Speicherstelle 930 Sprites vom Anfang des oberen bis zum Anfang des unteren Randbereichs sichtbar gemacht werden.
Zur Bedienung des Programms:
Nach der Initialisierung mittels SYS 828 werden Sprites nicht mehr durch POKE 53269,X ein- oder ausgeschaltet, sondern durch POKE 930,X1 und POKE 931,X2. Das Bitmuster (!) von X1 gibt an, welche Sprites Y-Koordinaten von 0 bis 255 haben, X2 enthält das Bitmuster der Sprites mit Y-Koordinaten über 255. Ansonsten werden die Y-Koordinaten in den normalen Registern von 53249 bis 53263 eingetragen. Auf diese Weise sind Y-Koordinaten von 0 bis 511 möglich, wobei die Sichtbarkeit der Sprites je nach vorhandenem Monitor oder Fernsehgerät variiert.
Normalerweise sind Sprites mit Y-Koordinaten von 290 gerade noch sichtbar.
Hierzu einige Beispiele:
POKE 930,PEEK(930)OR2↑3:POKE 931,PEEK(931)AND(255-2↑3):
POKE 53249 + 2*3,5 — Sprite 4 hat die Y-Koordinate 5
POKE 930,PEEK(930)AND(255-2↑7):POKE 931 ,PEEK(931) OR 2↑7:
POKE 53249 + 7*2,7 — Sprite 8 hat die Y-Koordinate 262
POKE 930,PEEK(930)OR2↑O:POKE 931,PEEK(931)OR2↑O:
POKE 53249,3 — Sprite 1 hat die Y-Koordinaten 3 und 258, ist also zweimal auf dem Bildschirm sichtbar.
So ist eine Darstellung von 16 Sprites möglich. Das Demoprogramm im Listing 5 bewegt ein Sprite über den erweiterten Bildschirm.
Noch ein Tip zur Verwendung dieses Utilitys:
Beim Einbau in eigene Programme sollten Sie darauf achten, daß die letzte vom VIC ll-Chip addressierbare Speicherstelle, also im Normalfall 16383, den Wert 0 besitzt, da sonst schwarze Streifen Ihren Bildrand verunstalten.
(Anton Ernst/tr)PROGRAMM : SCREENENLARGER 033C 03A4 ----------------------------------- 033C : 78 A9 7F 8D 0D DC A9 5D 33 0344 : 8D 14 03 A9 03 8D 15 03 C8 034C : A9 01 8D 1A D0 A9 F7 8D 72 0354 : 12 D0 A9 00 8D FF 3F 58 BF 035C : 60 78 AD 19 D0 8D 19 D0 06 0364 : AD 12 D0 C9 F8 D0 0D A9 25 036C : 17 8D 11 D0 A9 FF 8D 12 9D 0374 : D0 4C 81 EA C9 FF D0 13 2E 037C : AD A3 03 8D 15 D0 A9 28 3C 0384 : 8D 12 D0 A9 97 8D 11 D0 4F 038C : 4C 81 EA A9 1B 8D 11 D0 8D 0394 : A9 F8 8D 12 D0 AD A2 03 6A 039C : 8D 15 D0 4C 31 EA C0 CE 7C
10 poke53248,100:poke53287,7:poke2040,11:fori=0to63:poke704+i,255:next 20 fori=0to290:poke53249,i+255*(i>255):poke930,-(i<256):poke931,-(i>255):next:goto20
Die Commander-Datasette streikt nie wieder
Der Artikel über die Datasettenverbesserung hat bei mir und auch bekannten Computer-Fans Anklang gefunden. Leider mußte ich bald darauf feststellen, daß die Einbauanleitung des Komperators nur für die neue Datasette ausgelegt war. Ein Computerkollege, der leider nur eine Datasette des Typs »Commander — Computer Datasette Model NO: PM-4401C« hat, und den Komperator einbauen wollte, stieß dabei auf diese Schwierigkeiten und bat mich als Elektroniker um Abhilfe. Nach detaillierten Messungen mit dem Oszilloskop fand ich dabei die Anschlüsse heraus und baute den Komperator in seiner Datasette ein. Um auch anderen Computerfans die Möglichkeit zu geben, sich die Schaltung in ihre Commander-Datasette einzubauen, zeigen die beiden Pfeile in Bild 1 den Anschluß an die Platine.
(Peter Ehlert/tr)