Tips & Tricks zum C 128
Weiter geht’s mit den Tips und Tricks. Diesmal dabei: Variablendump, ein FIND-Befehl, C 64-Modus im 2-MHz-Takt, ein Trick zur 1571 und vieles mehr.
Tips und Tricks nutzen jedem Anwender. Wie könnte man seine Maschine sonst ausnutzen, wenn man nicht die kleinen Kniffe wüßte, die dem Computer die Feinheiten entlocken. Lesen Sie hier, wie Sie Ihren C 128 bändigen.
Cursor auch bei GET
Mit dieser kleinen Zeile, die als Erste in einem Programm stehen muß, können Sie beim C 128 auf dem 80-Zeichen-Bildschirm den Cursor bei GET blinken lassen:
0 PRINT CHR$(27)+"U"
Komfortable Joystick-Abfrage
Dieses Programm ermöglicht eine komfortable Joystickabfrage. Statt umständlichen IF..THEN-Anweisungen werden einfach indizierte Variablen benutzt.
Zum Programm
In den Zeilen 40 und 50 werden die Variablen A(X) und B(X) definiert. Der Index X entspricht den Richtungen 1 bis 8 des Joysticks.
In Zeile 60 wird die Variable J mit dem Zustand des Joysticks in Port 1 belegt. Ist der Feuerknopf gedrückt (Richtung+128), springt das Programm wieder zu Zeile 60 (es würde sonst zu einer Fehlermeldung kommen).
In Zeile 70 werden jetzt die Werte der Variablen A(J) und B(J) zu der X- und Y-Position dazuaddiert. Dabei kommt uns ein Gesetz der Mathematik zugute: Addiert man zu einer positiven eine negative Zahl, kommt dies einer Subtraktion gleich (zum Beispiel: 100 + (-20) = 80).
Mit X und Y können jetzt Sprites, Shapes oder ähnliches bewegt werden (hier ist es ein Sprite).
Ein Beispiel für die Arbeitsweise
Wird der Joystick nach Rechts-Oben bewegt, ist J = 2; also ist A(J) = 1 und B(J)=-1. Angenommen, X = 100 und Y=90, so ist X + A(J) = 101 ((100 +1 = 101)) und Y+ B(J) = 89 ((90 + (-1) = 89)).
Es ist natürlich möglich, auch andere Schrittweiten als 1 zu nehmen, vorausgesetzt, X und Y sind nicht größer oder kleiner als die zugelassenen Werte.
10 X=160:Y=100
20 SPRDEF:SPRITE 1,1,2
30 COLOR 0,1:COLOR 4,1
40 A(1)=0:B(1)=-1:A(2)=1:B(2)=-1:A(3)=1
50 B(3)=0:A(4)=1:B(4)=1:A(5)=0:B(5)=1
60 A(6)=-1:B(6)=1:A(7)=-1:B(7)=0
70 A(8)=-1:B(8)=-1
80 J=JOY(2):IF J>127 THEN J=J-128
90 X=X+A(J):Y=Y+B(J)
100 MOVSPR 1,X,Y:GOTO 80
Eine Grafik-Routine
Mit dem kleinen Programm
10 GRAPHIC 1,1:COLOR 4,15
20 COLOR 1,2:Color 0,8
30 DO UNTIL E=180
40 E=E+4
50 CIRCLE 1,159,99,E,,,,E,72
60 LOOP
läßt sich mit wenig Aufwand eine schöne Grafik berechnen, die auf dem HiRes-Schirm dargestellt wird.
Zwei nützliche Hilfsroutinen
Das Programm UNDIM.VAR.DUMP (Listing 1) gibt auf dem aktuellen Ausgabegerät die nicht DIMensionierten Variablen aus. Der Aufruf erfolgt mit GOTO 63000.
Das Programm F.KEY-DISPLAY (Listing 2) stellt vier zusätzliche Bildschirmzeilen zur Verfügung, in denen die beim Aufruf gültige Belegung der Funktionstasten angezeigt werden. Es ist nötig, vor dem Start den 80-Zeichen-Modus eingeschaltet zu haben.
63000 fast:bank 1:fori=peek(47)+peek(48)*256topeek(49)+peek(50)*256-1step7 63010 forii=0to6:s(ii)=peek(i+ii):next 63020 if s(0)>128 and s(1)<128 then begin:rem def fn-variable 63030 print"def fn";chr$(s(0)and127);chr$(s(1)and127) 63040 bend 63050 if s(0)>128 and s(1)>=128 then begin:rem integer-var 63060 printchr$(s(0)and127);chr$(s(1)and127);"%";tab(4);"="; 63070 s(4)=s(3)+s(2)*256:ifs(4)>32767 then s(4)=s(4)-65536 63080 prints(4):bend 63090 if s(0)<128 and s(1)<128 then begin:rem real 63100 printchr$(s(0)and127);chr$(s(1)and127);tab(4);"="; 63110 s(2)=s(2)-129 63120 ifs(3)>127then s(3)=s(3)-128:ma=-1:else ma=1 63130 s(3)=s(3)/128 63140 s(4)=s(4)/128/256 63150 s(5)=s(5)/128/256^2 63160 s(6)=s(6)/128/256^3 63170 s(0)=ma*2^s(2)*(1+s(3)+s(4)+s(5)+s(6)) 63180 prints(0) 63190 bend 63200 if s(0)<128 and s(1)>=128 then begin:rem string-var 63210 printchr$(s(0)and127);chr$(s(1)and127)"$";tab(4);"= "; 63220 printchr$(34);:s(0)=s(3)+s(4)*256 63230 ifs(2)<>0then begin 63240 for o=0tos(2)-1:printchr$(peek(s(0)+o));:next:printchr$(34) 63250 bend:else printchr$(34) 63260 bend 63270 next 63280 end
100 fast:color6,16:color5,1:print"{clr}";:bank15:v1=54784:v2=v1+1
110 pokev1,20:pokev2,16
120 poke 2607,16
130 pokev1,06:pokev2,29
140 pokev1,07:pokev2,34
150 gosub420
170 o=49:f=4096:t=4106:fori=2000to 2319
180 a=i / 256
190 x=i and 255
200 y=6
210 :sys 3340,a,x,y
220 i=i+1
230 a=i / 256
240 x=i and 255
250 y=o
260 :sys 3340,a,x,y
270 i=i+1
280 a=i / 256
290 x=i and 255
300 y=61
310 :sys 3340,a,x,y
320 i=i+1
330 ft=peek(f+o-49):rem laenge des strings der funktionstaste
340 forii=itoi+38
350 a=ii / 256
360 x=iiand 255
370 : if ii>=ft+i then y=32:else ifpeek(t+ii-i)<>13then y=peek(t+ii-i)and63:elsey=31
380 :sys 3340,a,x,y
390 next:o=o+1:i=2000+(o-49)*40:t=t+ft
410 i=i-1:next:goto600
420 rem
430 for i=0 to 45
440 : read x
450 : poke 3328+i,x
470 next
500 data 142,0,214,44,0,214,16,251,141,1,214,96,141,24,13,142,30,13,140,37,13
510 data 162,18,169,0,32,0,13,232,169,0,32,0,13,162,31,169,32,32,0,13
520 data 162,18,76,0,13
530 :
540 return
600 fori=iito2319
610 a=i / 256
620 x=i and 255
640 y=32
650 : sys 3340,a,x,y
660 next
700 rem attributram veraendern
710 fori=6096to6096+319
720 a=i / 256
730 x=i and 255
735 y=66 + 128
740 : sys 3340,a,x,y
745 next:end
800 fori=2000 to2319:sys 3340,iand255,i/256,32:next
Auch im C 64-Modus mit 2 MHz
Laut Auskunft bei Commodore ist es möglich, den C 128 im C 64-Modus mit 2 MHz arbeiten zu lassen. Diese wenigen Programmzeilen wirken wie FAST beim C 128 im 40-Zeichen-Modus.
Das bedeutet, der Computer arbeitet mit 2 MHz. Jedoch ist es nicht möglich, im C 64-Modus über die RGBI-Buchse zu gehen und somit die Arbeit am Bildschirm zu verfolgen.
Diese POKEs eignen sich also besonders für die Leute, die ihre eigenen Basic V2-Programme zwar nicht umschreiben, aber doch die volle Geschwindigkeit des C 128 nutzen wollen. Sie können sie als kleine Routine vor den Rechenteil Ihres Programmes setzen.
10 POKE 53265,PEEK (53265) AND 239: REM Video aus
20 POKE 53296,PEEK (53296) OR 1: REM 2 MHz an
30 FOR A = 1 TO 1000:NEXT A: REM Programmteil
40 POKE 53296,PEEK (53296) AND 254: REM 1 MHz an
50 POKE 53265,PEEK (53265) OR 16: REM Video an
Ein FIND-Befehl
Obwohl das Basic 7.0 des Commodore 128 viele neue Befehle beinhaltet, gibt es doch einige, die man vermißt. Ein solcher ist der von vielen Erweiterungen für den C 64 her bekannte Befehl FIND Der hier abgedruckte Basic-Lader (Listing 3) bringt dem C 128 eine solche Routine bei.
Aktiviert wird die Routine mit SYS DEC("1300"). Nun können Sie Ihr Basic-Programm nach einem Begriff durchsuchen. Als Befehlserkennung dient der Klammeraffe @. Danach schreiben Sie das Suchwort (zum Beispiel einen Befehl, einen String oder einen Variablennamen). Wenn eine Zeile gefunden wird, in der der Begriff auftaucht, so wird die komplette Zeile auf dem Bildschirm gelistet (mit OPEN l,4:CMD 1 auch auf dem Drucker).
Das Listen kann mit der Commodore-Taste verlangsamt und mit der NO SCROLL-Taste aufgehalten werden. Wenn der Klammeraffe in einer Zeile (Bildschirmzeile, nicht Programmzeile) steht, so ist davor ein Doppelpunkt einzugeben.
Hier noch einige Beispiele:
: @DATA — listet alle DATA-Zeilen
: @GOTO 10 — listet alle Zeilen, in denen GOTO 10 vorkommt, aber auch GOTO 100, GOTO 1000 etc.
: @"MESSUNG " — alle Zeilen, in denen der String gefunden wird, werden gelistet.
10 rem find fuer pc 128
20 rem ****
30 rem
40 rem (c) herbert kunz
50 rem
60 rem 12/1985
70 rem
100 data a9,0b,8d,08,03,a9,13,8d
101 data 09,03,60,20,80,03,c9,40
102 data f0,06,20,86,03,4c,f3,4a
103 data a9,00,85,fa,a2,00,20,80
104 data 03,f0,ef,20,29,13,4c,f6
105 data 4a,c9,22,d0,07,a9,01,85
106 data fa,4c,43,13,9d,00,0c,e8
107 data 20,80,03,d0,f7,9d,00,0c
108 data 4c,5c,13,20,80,03,c9,22
109 data f0,06,9d,00,0c,e8,d0,f3
110 data a9,00,9d,00,0c,20,80,03
111 data a9,01,85,fa,a5,2d,85,fc
112 data a5,2e,85,fd,a9,00,85,fb
113 data a0,01,20,df,13,f0,9b,a0
114 data 04,a2,00,20,df,13,48,c9
115 data 22,d0,06,a9,01,45,fb,85
116 data fb,68,f0,46,48,a5,fa,c5
117 data fb,f0,05,68,c8,4c,71,13
118 data 68,dd,00,0c,f0,03,c8,d0
119 data da,c8,e8,bd,00,0c,f0,0e
120 data 48,20,df,13,85,63,68,c5
121 data 63,f0,ee,4c,71,13,a9,0d
122 data 20,0c,56,a5,fc,85,61,a5
123 data fd,85,62,a0,03,20,df,13
124 data 48,88,20,df,13,aa,68,20
125 data 23,51,a0,00,20,df,13,aa
126 data c8,20,df,13,85,fd,86,fc
127 data a5,91,c9,7f,d0,86,60,a9
128 data fc,4c,9f,03
129 s=0:fori=4864to5091:reada$:a=dec(a$)
130 pokei,a:s=s+a:next
131 print"die datazeilen sind ";
132 ifs<>25906thenprint"fehlerhaft":stop
133 print"in ordnung":sysdec("1300")
Programme transferieren mit FLASHMOVE
Spielen Sie folgenden Gedankengang einmal durch: Sie besitzen einen C 128 und eine Floppy 1570/1571. Diese Gerätekombination besitzt die gute Eigenschaft, daß im C 128-Modus lange Programme in wenigen Sekunden geladen werden können. Sie möchten aber Ihre C 64-Software aktiv weiterbenutzen. Also nichts wie GO 64 eingeben und das entsprechende Programm laden…
Man freut sich immer wieder, daß ein Programm im C 64-Modus nur so »reinfetzt«, was gewöhnlich bei längeren Programmen zu erfreulich »langen« Wartezeiten führt. Es muß also eine Programmroutine her, die es ermöglicht, ein im C 128-Modus geladenes Programm in den C 64-Modus umzuwandeln, so daß man es dort wie gewohnt weiterverwenden kann. Die Lösung: »Flashmove«.
Da Bank 0 sowohl im C 128- als auch im C 64-Modus für die Speicherungvon Basic-Programmen dient, der Basic-Anfang aber verschoben ist (C 128: $lC00, C 64: $0800), liegt es nahe, daß ein im C 128-Modus geladenes Programm nur noch verschoben werden muß, um es im C 64-Modus zu gebrauchen. Und eben das erledigt das Programm »Flashmove« (Listing 4).
Der einzige Nachteil der Sache ist, daß das Programm nicht länger als 45 KByte sein darf. Übrigens, wenn die Startadresse eines Programmes über $lC00 liegt, benötigt man Flashmove nicht.
Bank 0 wird durch GO 64 nur in die C 64-Speicherverwaltung umgeschaltet, aber nicht total gelöscht.
Und so benutzt man Flashmove im C 128-Modus:
1) »Flashmove« (wird als % gespeichert) mit ,8,1 laden
2)LOAD "beliebiges Programm" ,8
3) GO 64
4) »Flashmove« mit SYS 2060 starten, fertig
Eingabehinweise
Um den Maschinencode von Flashmove zu erhalten, geht man folgendermaßen vor:
- Zuerst geben Sie bitte das Listing »Flashmove« (Listing 4) ein und speichern es
- Nach dem Start durch RUN wird auf zwei Bildschirmseiten die Funktion und Handhabung nochmals beschrieben
- Schließlich wird man nach dem Namen gefragt, unter welchem Flashmove gespeichert werden soll (ACHTUNG: ist schon ein File mit gleichen Namen auf Diskette vorhanden, so wird dieses gelöscht)
Mit dem »Autoboot Maker« (zu finden auf der 1570/1571 Test/Demo-Disk) kann man nun den abgespeicherten Maschinencode bootfähig machen: - »Autoboot Maker« laden und starten
- Den Namen eingeben, unter dem das Maschinenprogramm von Flashmove gespeichert wurde
- Die Frage nach dem Datentyp beantwortet man mit »binary«
10 printchr$(14):scnclr:color4,1:color0,1 11 print" ******************************* 12 print" ******************************* 13 print" *** Flashmove V2 *** 14 print" *** *** 15 print" *** (c) Stefan Seidenberg *** 16 print" *** Auf der Schmitt 25 *** 17 print" *** 5470 Andernach *** 18 print" *** Tel:(02632)42325 *** 19 print" *** *** 20 print" *** 28. Feb. 1986 *** 21 print" ******************************* 22 print" ******************************* 23 print:printtab(7)"Fuer PC-128 und 1570/1571":poke162,0:wait162,128 24 fast:scnclr 25 print"PC-128"tab(10)chr$(18)" Flashmove V2 "chr$(146)" 1570/1571 26 print:print"Flashmove verschiebt Programme vom 27 print"PC-128er Basicanfang an den C-64er 28 print"Basicanfang. So kann man im 128er Modus 29 print"Programme mit der 1570/1571 in wenigen 30 print"Sekunden laden und nach Aufruf dieses 31 print"Programmes im 64er Modus ohne Probleme 32 print"weiterverwenden. 33 print"Die Programme duerfen bis 45k lang sein! 34 print:print:print"Die Ihnen nun vorliegende 2. Version 35 print "von 'Flashmove' ist erweitert worden: 36 print:print"1. Nach dem Aufruf von 'Flashmove V2' 37 print" erscheint 'Run' auf dem Bildschirm. 38 print" Will man das verschobene Programm 39 print" jetzt starten, so drueckt man einfach 40 print" 'RETURN'. 41 print: print"2. 'Flashmove V2' ist bootfaehig!! 42 gosub73 43 fast:scnclr:print"Dieses Programm speichert 'Flashmove V2' 44 print"als Maschinencode ab. Dieser kann sowohl 45 print"manuell geladen, als auch als Autoboot- 46 print"Programm generiert werden. Dazu benutzt 47 print"man den auf der PC-128 Test/Demo 48 print"Diskette befindlichen 'Autoboot Maker'. 49 print:print"'Flashmove V2' benutzt man wie folgt: 50 print"Der PC-128 befindet sich im 128er-Modus. 51 print"Man gibt eine der folgenden Befehles- 52 print"sequenzen ein: 53 print:print"1. Load'Flash*',8,1 1. Load'Name',8 54 print"2. Load'Name' ,8 2. go 64 55 print"3. go64 3. Load'Flash*',8,1 56 print"4. sys 2060 4. sys 2060 57 print:print"1. Boot 1. load'Name',8 58 print"2. Load'Name',8 2. Boot 59 print"3. go 64 3. go 64 60 print"4. sys 2060 4. sys 2060 61 print"-> Nun kann das Programm benutzt werden. 62 gosub73 63 scnclr:print"Bitte legen Sie nun eine formatierte 64 print"Diskette in das Laufwerk! 65 print"Der Maschinencode von 'Flashmove V2' 66 print"wird abgespeichert. 67 print:poke208,0:input"Filename:";f$ 68 scratch (f$) 69 open1,8,1,f$:print#1,chr$(12)chr$(8); 70 reada:ifa<>-1 then print#1,chr$(a);:x=x+a:goto70 71 close1:ifx<>13269 then print:print"Pruefsummenfehler!! 72 print:print"Diskstatus: "ds$:end 73 slow:char1,2,24,"(c) 1986 by Stefan Seidenberg":poke208,0 74 if peek(208)<>0 then return 75 char 1,0,23," ":poke162,0:wait162,32:char 1,0,23,"Taste"+chr$(7) 76 poke162,0:wait162,32:goto74 77 data165,44,201,8,208,101,162,0,189,32,8,157,0,4,232,16,247,76,0,4,169,1 78 data141,32,208,173,17,18,133,2,56,233,20,133,46,173,16,18,133,45,120,169 79 data118,133,1,169,0,133,251,133,253,169,28,133,252,169,8,133,254,160,0 80 data177,251,145,253,200,208,249,165,252,197,2,240,6,230,252,230,254,208 81 data235,169,119,133,1,88,169,0,141,32,208,169,82,141,119,2,169,213,141 82 data120,2,169,2,133,198,76,51,165,96,-1
Sprites invertieren
Dieses kleine Programm (Listing 5) (re)invertiert Sprites, die im Speicher abgelegt sind. Der Aufruf der Routine ist sehr einfach. Die Syntax lautet:
SYS anfadr, sprnr
- anfadr steht für die Startadresse des Maschinenprogrammes im Speicher (zum Beispiel $0b00 bzw. dez. 2816)
- sprnr steht für die Nummer des zu (re)invertierenden Sprites. Ist die Spritenummer größer 8 oder kleiner gleich 0, erfolgt ein ILLEGAL QUANTITY ERROR, auch im Programmmodus. Die fehlerhafte Zeile läßt sich dann mit HELP listen.
Das Programm ist an keine bestimmte Adresse gebunden und kann durch Ändern der Startadresse oder dem T(ranslate)-Befehl des Monitors an eine andere Adresse verschoben werden.
Die Vorzüge der Routine liegen vor allem in der Geschwindigkeit, in der diese ausgeführt wird. Außerdem geht kein Basic-Speicher verloren. Für Assembler-Fans ist in Listing 6 der kommentierte Quellcode abgedruckt.
100 rem ******************************* 110 rem * sprinv 1.0 * 120 rem * * 130 rem * (c)1986 by udo miller * 140 rem ******************************* 150 : 160 color0,1:color4,1:scnclr 170 print"startadresse (z.b. dez. 2816)"; 180 inputad 190 : 200 do 210 read a$:ifa$="ende"thenexit 220 pokead+i,dec(a$) 230 i=i+1 240 loop 250 : 260 data c9,00,f0,06,c9,08,90,07,f0,05,a2 270 data 0e,6c,00,03,aa,ca,a9,00,86,fc,a0 280 data 00,84,fa,a0,0e,84,fb,e0,03,f0,0b 290 data 90,09,e6,fb,a9,fb,65,fc,aa,86,fc 300 data a0,00,a9,00,c4,fc,f0,07,c8,69,40 310 data c4,fc,d0,f9,85,fa,a0,00,b1,fa,49 320 data ff,91,fa,c8,c0,40,d0,f5,60 330 data ende
00b00 c9 00 cmp #$00 ;Akku(Spritenummer)= 0, wenn ja
00b02 f0 06 beq $0b0a ;dann Fehlermeldung
00b04 c9 08 cmp #$08 ;Akku(Spritenummer)<=8, dann
00b06 90 07 bcc $0b0f ;weiter ab $0b0f
00b08 f0 05 beq $0b0f ;sonst
00b0a a2 0e ldx #$0e ;Fehlermeldung ($0e)
00b0c 6c 00 03 jmp ($0300) ;illegal quantity und STOP!!
;Beginn Hauptprogramm
00b0f aa tax ;Zuweisung des Akku ins X-Register
00b10 ca dex ;und um 1 verringern
00b11 a9 00 lda #$00 ;Hilfszeiger mit
00b13 86 fc stx $fc ;der Basisadresse des
00b15 a0 00 ldy #$00 ;Spritedatenspeichers laden
00b17 84 fa sty $fa ;und sichern
00b19 a0 0e ldy #$0e ;
00b1b 84 fb sty $fb ;
00b1d e0 03 cpx #$03 ;wenn X-Register <=3, dann
00b1f f0 0b beq $0b2c ;Sprung nach $0b02,
00b21 90 09 bcc $0b2c ;andernfalls
00b23 e6 fb inc $fb ;HI-Byte(Zeiger) um 1 erhöhen,
00b25 a9 fb lda #$fb ;Akku mit #$fb laden und
00b27 65 fc adc $fc ;in Zelle $fc addieren
00b29 aa tax ;Zuweisung des Akku ins X-Register
00b2a 86 fc stx $fc ;und sichern
00b2c a0 00 ldy #$00 ;Y-Register und
00b2e a9 00 lda #$00 ;Akku löschen
00b30 c4 fc cpy $fc ;wenn Y-Register = Zelle $fc
00b32 f0 07 beq $0b3b ;weiter ab $0b3b, sonst
00b34 c8 iny ;Y-Register erhöhen und
00b35 69 40 adc #$40 ;#$40 zum Akku addieren
00b37 c4 fc cpy $fc ;wenn Y-Register <> Zelle $fc,
00b39 d0 f9 bne $0b34 ;dann wieder zu $0b34
00b3b 85 fa sta $fa ;LOW-Byte(Zeiger) sichern
00b3d a0 00 ldy #$00 ;Y-Register löschen
00b3f b1 fa lda ($fa),y ;Akku durch Hilgszeiger laden,
00b41 49 ff eor #$ff ;invertieren und
00b43 91 fa sta ($fa),y ;zurückschreiben
00b45 c8 iny ;Y-Register erhöhen und
00b46 c0 40 cpy #$40 ;mit #$40 vergleichen,
00b48 d0 f5 bne $0b3f ;wenn <> dann zu $0b3f
00b4a 60 rts ;ENDE
Noch ein kleiner Trick
Der C 128 bietet ja eine variable Funktionstastenbelegung mit dem Befehl KEY. Will man eine selbsterstellte Belegung auf Diskette speichern, so kann man folgende Befehlsfolge benutzen: BSAVE"FUNKTIONS-T.",D0,U8,0NB0,P4096 TO P4352
Damit wird der Bereich der Funktionstasten (4096 bis 4352) gespeichert. Geladen wird er mit: BLOAD"FUNKTIONS-T."
(Holger Brömmelsiek/dm)