C 64
Tips und Tricks

Tips & Tricks für Anfänger und Profis

In der Rubrik Tips & Tricks können wir Ihnen diesmal einige Routinen anbieten, die sich besonders zum Einbau in eigene Programme eignen.

Screen-Dump

Eine Bildschirmmaske kann auf viele verschiedene Arten auf den Bildschirm gebracht werden. Die einfachste ist wohl: FOR I = 0 T0 999 : POKE 1024 + I, PEEK (STADR + I) : NEXTI wobei STADR die Startadresse der Maske ist. Doch das ist zu langsam und eintönig. Das gleiche Programm in Assembler ist zirka 200 mal schneller, aber immer noch eintönig.

Das Programm »Screen-Dump« (siehe Listing 1) hilft dem ab. Auf über 100 verschiedene Arten kann hiermit das oben genannte Programm ablaufen (das heißt 100 verschiedene Reihenfolgen), von denen einige verblüffen, fast alle aber besser »aussehen« als dieses Programm. Auch die verstellbare Geschwindigkeit ermöglicht interessante Veränderungen.

Die Handhabung ist denkbar einfach: SYS 680, Art, Stadr., Geschwindigkeit

Also SYS 680, 20, 64, 8 kopiert den Bereich von 16384 bis 17383 auf sehr originelle Weise in den Bildschirm.

Andere »schöne Versionen« sind:

Art Geschw. Art Geschw.
2 1 6 4
9 4 13 8
19 2 20 8
28 8 33 4
36 10 44 4
46 20 61 20
64 4 65 10
66 4 84 4
88 2 98 8
104 4 106 2
120 20 125 20

Funktionsweise

Wie funktioniert Screen-Dump, wo es doch nur 100 Byte lang ist? Am besten ist das an folgendem Beispiel zu erkennen: Wir nehmen eine Gruppe von zwölf Elementen. Wie greift man nun nacheinander auf alle zwölf Elemente zu, so daß keine Reihenfolge erkennbar wird? Ganz einfach:

Wir nehmen eine Zahl, die mit 12 keinen gemeinsamen Teiler hat, zum Beispiel 5. Jetzt beginnen wir bei 0 und zählen 5 hinzu. Diese Zahl nehmen wir heraus. Dann zählen wir wieder 5 hinzu. Ergebnis 10. Unser zweites Element. Dann wieder + 5 = 15. Element 15 ist nicht vorhanden, also ziehen wir die Gesamtanzahl der Elemente ab. 15—12=3 und so weiter. Es ergibt sich die Reihenfolge: 5 10 3 8 1 6 11 4 9 2 7 12. Augenscheinlich völlig wahllos. Es funktioniert immer, wenn folgende Voraussetzungen erfüllt sind:

  1. Die Additionszahl (hier: 5) muß kleiner sein als die Gesamtzahl der Menge.
  2. Die Additionszahl darf mit der Gesamtzahl keinen gemeinsamen Teiler haben.

Im Screen-Dump wird dieses System mit einer Menge von 1 024 Elementen angewandt. Die möglichen Additionszahlen sind somit alle ungeraden Zahlen zwischen 0 und 255.

(Michael Schmidt/tr)
10 fori=659to763:readj:pokei,j:next:print"{wht}{clr}{down}sys 680,art,block,geschwindigkeit{lblu}
20 new
1000 data164,6,162,32,202,208,253,136,208,248,96,0,0,0,0,0,0,0,17,1,0,32,155
1001 data183,134,2,32,155,183,134,5,32,155,183,134,6,165,2,10,9,1,133,97,169
1002 data4,162,0,134,2,133,3,134,4,160,0,177,4,145,2,165,2,24,101,97,133,2
1003 data133,4,144,4,230,3,230,5,165,3,201,8,208,11,169,4,133,3,165,5,56,233
1004 data4,133,5,32,147,2,165,2,208,211,165,3,201,4,208,205,96
Listing 1, »Screen-Dump«, mit dem Checksummer eingeben.

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 2) 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:

(Guido Schuhmacher/tr)
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
Listing 2. »Pseudo-IRQ«. Bitte mit dem MSE eingeben.

List-Schutz für Basic-Programme

Dieser List-Schutz ist für Nichteingeweihte sehr verblüffend. Die Grundidee dazu stammt aus dem Bericht »Disketten-Manipulationen« aus 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 folgende zwei Zeilen ein:

1 poke2067,73:goto 10
2 rem"a{clr}{down}{down}{down}{yel}it is not allowed to list this program{blu}aa

Danach gibt man im Direktmodus POKE 2067,71 : POKE 2073,141 : POKE 2118,0 : POKE 2119,0 ein und speichert das Programm.

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-Ende-Zeichen (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/tr)

Sichere INPUT-Routine in Basic

Ich habe bisher immer eine leistungsfähige INPUT-Routine in Basic vermißt. Das ging anscheinend nicht nur mir so, denn in einigen abgedruckten Programmen (zum Beispiel Ligatab, Listing des Monats, 3/85) fehlt eine solche Routine, was zu chaotischen Ergebnissen führen kann. (Wenn man zum Beispiel aus Versehen an Stelle der Shift-Taste die Crsr-Down-Taste gedrückt hat, so nützt es dem Anwender wenig, wenn er mit der Crsr-Up-Taste wieder in das Eingabefeld zurückkehrt, weil jetzt der INPUT-Befehl die ganze Zeile als Eingabe ansieht.) Deshalb hier eine INPUT-Routine, die folgende Vorteile hat:

  1. Da die Routine (Listing 3) in Basic geschrieben ist, ist sie für jeden Programmierer leicht verständlich und abänderbar,
  2. Der Programmierer kann beim Aufruf der Routine gleich Ort, mini- und maximale Länge und die zulässigen Zeichen der Eingabe festlegen.
  3. Jedes Zeichen wird gleich bei der Eingabe auf seine »Richtigkeit« überprüft.
  4. Es wird nur die tatsächliche Eingabe als Eingabe übernommen (und nicht noch eventuell Teile der Maske).
  5. Es funktionieren noch sämtliche Sonderfunktionstasten (inst, del, home, clr und so weiter).
  6. Der Anwender kann das Eingabefeld nicht verlassen.
  7. Die Routine ist mit 1,5 KByte relativ kurz.

Benutzung der Routine:

  1. Setzen des Parameterstrings
  2. Aufruf mit gosub 60000
  3. Übergabe von in$ an gewünschte Variable

Der Parameterstring:

Er setzt sich zusammen aus:

Stelle 1,2 Zeile der Eingabe
Stelle 3,4 Spalte der Eingabe
Stelle 5,6 minimale Länge der Eingabe
Stelle 7,8 maximale Länge der Eingabe
Stelle 9 Code (siehe weiter unten)

Es ist darauf zu achten, daß einstellige Angaben (zum Beispiel: 3. Zeile) mit 03 angegeben werden, da sonst keine klare Trennung der einzelnen Parameter vorgenommen werden kann.

Die Routine sieht Standardwerte für die minimale und maximale Länge und für den Code der Eingabe vor (Zeile 60200). Diese können natürlich frei nach eigenem Bedarf eingerichtet werden. Entspricht die geforderte Eingabe den Standardwerten, so braucht der Programmierer beim Setzen des Parameterstrings diese Werte nicht anzugeben, sondern nur noch Zeile und Spalte. Dies führt natürlich zu einer weiteren Vereinfachung (Beispiel: pa$ = "0510", das heißt Eingabe in Zeile 5 ab Spalte 10 mit den Standardwerten).

Code (c)

Der Code dient dazu, die eingegebenen Zeichen sofort zu überprüfen. Selbstverständlich kann auch er frei programmiert werden. In Zeile 60490 wird entsprechend dem Code in die Unterprogramme verzweigt. Dort wird die gedrückte Taste überprüft. Entspricht sie nicht dem Code, wird f1 auf 1 gesetzt.

In der vorliegenden Routine sind Code 1 bis 4 schon programmiert, wobei

zulässig sind.

Diese Codes oder auch neue Codes können spielend leicht geändert oder neu programmiert werden.

Funktionen der Sondertasten:

CRSR UP,CRSR DOWN sind abgeschaltet
INST,DEL funktionieren innerhalb des Eingabefensters wie gewohnt (Rest der Maske wird nicht berührt)
HOME springt an Anfang des Eingabefensters
CLR löscht Eingabefenster und springt an den Anfang desselben
CRSR LEFT,RIGHT funktionieren wie gewohnt, nur Eingabefeld kann nicht verlassen werden.
(Karlheinz Boss/tr)
Variablenliste
pa$ Parameterstring; dient der Übergabe der Parameter
bl$ String, der nur aus Spaces besteht
in$ Eingabe
n$ gedrückte Taste
ze Zeile für die Eingabe
sp Spalte, ab der die Eingabe erfolgen soll
mi minimale Länge der Eingabe
ma maximale Länge der Eingabe
c Code, welchem die Eingabe entsprechen muß
ss aktuelle Cursorspalte
fl Flag, ob zuletzt gedrückte Taste Code entsprach
Programmbeschreibung
0 rem       input (demo)
1 rem input-routine fur vc 64
2 rem
3 rem copyright by
4 rem karlheinz boss
5 rem sylvester-jordan-str. 11
6 rem 3550 marburg
7 rem 06421/13509
8 poke53281,09:poke53280,09:poke646,07
9 print chr$(14)
10 rem input-routine
20 rem
30 rem pa$ ist aufgebaut wie folgt:
40 rem pa$ = zespmimac     wobei
50 rem       ze = zeile
60 rem       sp = spalte
70 rem       mi = mindestlaenge
80 rem       ma = maximale laenge
90 rem        c = code  wobei
100 rem         1 = nur zahlen
110 rem         2 = nur buchstaben
120 rem         3 = alles
125 rem         4 = nur kleinbuchst.
130 rem       5-6 = frei programmierbar
132 rem               ( zeile 60490 )
140 rem pa$ muss die zeile und spalte
150 rem beinhalten,der rest ist hin-
160 rem reichend.es werden dann die
170 rem standardparameter in zeile
180 rem 60200 angenommen
190 rem z.b. pa$="0510"
200 :
1000 print"{clr}";
1010 print"{rvon}  Input-Routine   copyright by K.Boss   {rvof}"
1020 print "Ueber get wird eine Input-Routine simu-"
1030 print "liert, wobei saemtliche Sonderfunktions-";
1040 print "tasten (inst,del,home,clr,cr,cl) noch "
1050 print "funktionieren, man aber das Eingabefeld"
1060 print "nicht verlassen kann. Ausserdem kann man";
1070 print "beim Aufruf der Routine gleich Ort, min.";
1080 print "und max. Laenge und die zulaessigen Zei-";
1090 print "chen der Eingabe angeben."
1100 print "{rvon}{gry2} Beisp.:                                ";
1105 print "                                        ";
1110 print "Datum (TTMMJJ) :  {rght}{rght}{rght}{rght}{rght}{rght}                ";
1120 print "                                        ";
1130 print "Name :  {rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}            ";
1140 print "                                        ";
1150 print "Kuerzel (mind 2 kl. Buchst.) :  {rght}{rght}{rght}     ";
1160 print "                                        ";
1170 print "Computer :  {rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}{rght}             ";
1180 print "                                        {rvof}{yel}";
1900 rem hier nun die 4 aufrufe aus
1910 rem vorangegangen beispiel
1920 rem
2000 pa$="121806061":gosub60000:a$=in$
2010 pa$="140800202":gosub60000:b$=in$
2020 pa$="163202034":gosub60000:c$=in$
2030 pa$="1812":gosub60000:d$=in$
2040 rem
2100 rem     das war's
2110 rem
2120 rem ps: die reine input-routine
2130 rem in kompr. form heisst
2140 rem        input (kurz)
3000 print:print "Die Eingaben waren : ";a$
3010 print b$
3020 print c$
3030 print d$
3040 print "            {rvon} Taste druecken {rvof}";
3050 get nj$ : if nj$="" then 3050
3995 print"{clr}"
4000 poke 211,0:poke 214,24:sys58640
4010 print"list1900-2140          "
4015 print"{home}"
4020 list30-190
29999 end
30000 :
31000 :
32000 :
33000 :
34000 :
60000 bl$="                                        "
60010 in$=""
60099 :
60100 ze=val(mid$(pa$,1,2))
60110 sp=val(mid$(pa$,3,2))
60120 if len(pa$)=4 then 60200
60130 mi=val(mid$(pa$,5,2))
60140 ma=val(mid$(pa$,7,2))
60150 co=val(mid$(pa$,9,1))
60160 goto 60300
60190 rem******************************
60200 mi=0:ma=15:co=3
60210 rem******************************
60220 :
60300 gosub 60950
60310 poke 204,0
60320 get n$ : if n$="" then 60320
60330 ss=peek(211)
60340 if asc(n$)=13 and len(in$)>=mi then poke 204,1 : gosub 63890:return
60350 if asc(n$)=147 then gosub 61000 : goto 60320
60360 if asc(n$)=19 then gosub 63890 : gosub 60950:goto 60320
60370 if asc(n$)=20 and peek(211)>sp then gosub 61410 : goto 60320
60380 if asc(n$)=157 then gosub 61310:goto 60320
60390 if asc(n$)=148 and len(in$)<ma then gosub 61505:goto 60320
60400 if asc(n$)=29 then gosub 61210:goto 60320
60410 if asc(n$)=17 or asc(n$)=145 then   60320
60420 if asc(n$)=148 or asc(n$)=20 or asc(n$)=13 then goto 60320
60430 :
60485 fl=0
60490 on co gosub  63900,63910,63920,63930,63940,63950
60495 if fl=1 goto 60320
60500 :
60505 if len(in$)=ss-sp then in$=in$+n$:goto 60515
60510 in$=left$(in$,ss-sp)+n$+mid$(in$,ss-sp+2,len(in$)-ss+sp-1)
60515 print n$;
60520 if ss=sp+ma-1 then print chr$(157);
60530 goto 60320
60901 :
60902 :
60903 :
60950 poke211,sp:poke214,ze:sys58640:return
60999 :
61000 gosub 60950
61010 print left$(bl$,ma);
61020 gosub 60950
61030 in$=""
61040 return
61099 :
61210 if ss<sp+len(in$)and ss<sp+ma-1then ss=ss+1
61220 gosub 63890
61230 poke 211,ss:sys58640
61240 return
61250 :
61310 if ss>sp then ss=ss-1
61320 gosub 63890
61330 poke 211,ss : sys 58640
61340 return
61350 :
61410 in$=left$(in$,ss-sp-1)+mid$(in$,ss-sp+1,len(in$)-ss+sp)
61420 gosub 63890
61425 if len(in$)<ma-1 then print" ";
61430 poke 211,ss-1 : sys 58640
61440 return
61490 :
61505 if ss=sp+len(in$) then goto 61540
61510 in$=left$(in$,ss-sp)+" "+mid$(in$,ss-sp+1,len(in$)-ss+sp)
61520 gosub 63890
61530 poke 211,ss : sys 58640
61540 return
61590 :
63890 gosub 60950
63892 print in$;:if len(in$)<ma then print " ";
63898 return
63899 :
63900 if asc(n$)<48orasc(n$)>57 then fl=1
63909 return
63910 if asc(n$)=32 then return
63911 if(asc(n$)<65orasc(n$)>90)and(asc(n$)<193orasc(n$)>218) then fl=1
63919 return
63920 rem
63929 return
63930 if asc(n$)=32 then return
63931 if(asc(n$)<65orasc(n$)>90) then fl=1
63939 return
63940 rem
63949 return
63950 rem
63959 return
Listing 3. Die bedienungssichere Input-Routine mit eingebautem Demo.

Synthetische Melodien

Das wahrscheinlich kürzeste und erstaunlichste Musiksynthesizer-Sequencer-Programm, das je veröffentlicht wurde. Es handelt sich um ein 47 Byte langes Assemblerprogramm, das im Listing 4, in Form eines DATA-Laders vorliegt. Die Melodie und die Klangfarbe kann man über die Speicherstellen 1022 und 1023 einstellen. Dabei kommt es allerdings nur auf die Differenz der beiden Byte an. Es empfiehlt sich also, die Speicherstelle 1022 mit 0 zu belegen und für 1023 alle Werte von 0 bis 128 auszuprobieren.

Melodische Tonfolgen erreicht man mit POKE 1023,7 + 8*n, wobei n eine ganze Zahl zwischen 0 und 16 sein darf. Effektvolle Klänge erreicht man zum Beispiel über folgende Werte (POKE 1023,…): 11, 28, 62, 96, 130.

Funktionsweise

Zuerst werden Kurven- und Wellenform festgelegt. Die beiden Speicherinhalte von 1022 und 1023 werden erhöht beziehungsweise erniedrigt. Dann werden sie miteinander durch die AND-Funktion verknüpft. Das Ergebnis kommt ins High-Byte des Tonhöhenregisters. Eine kleine Warteschleife macht die Komposition hörbar.

(Wolfgang Horak/tr)
10 poke1022,0
20 input"parameter";a:poke1023,a
30 fort=0to46:readq:poket+832,q:next
40 sys832
50 data169,15,141,24,212,141,5,212,169,112,141,6,212,169,17,141,4,212,238
60 data255,3,206,254,3,162,0,16,0,200,208,253,232,224,7,208,246,173,255
70 data3,45,254,3,141,1,212,176,227
Listing 4 »Synthetische Melodien«. Bitte mit dem Checksummer eingeben.

Die Super-POKEs

POKE 792,226: POKE 793,252

Sobald die RESTORE-Taste gedrückt wird, wird ein Reset ausgelöst.

POKE 774,226: POKE 775,252

Sobald der LIST-Befehl eingetippt wird, wird ein Reset ausgelöst.

POKE 818,226: POKE 819,252

Sobald der SAVE-Befehl eingetippt wird, wird ein RESET ausgelöst.

(tr)

Tips & Tricks — Mischmasch

Und hier noch ein paar Kleinigkeiten für die Tips & Tricks-Sammlung:

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