Suchergebnisse für: Multiplattform

Multiplattform Programmierung

Als der C64 im Jahr 1982 auf den Markt kam, hatte er ein Problem nicht: fehlende Software. Zwei ganz wesentliche Eigenschaften waren dafür verantwortlich: zum einen das Commodore BASIC 2.0, das die sprachbarrierenfreie Übernahme der bereits für ältere Commodore-Rechner (PET 2001, CBM und VC20) geschriebene Programme ermöglichte und zum anderen der über POKE-Befehle direkt beschreibbare Bildschirm mit 25 Zeilen zu 40 Zeichen (dem Format von PET 2001 und CBM 3001/4001 Series). Nahm man von beidem die Schnittmenge, so ergab sich, dass alles was als BASIC-Programm auf einem CBM-Rechner mit 40-Zeichen-Bildschirm lief, mit wenig Aufwand auf einen C64 übertragbar war.

Zwar bot der C64 mit Farbe, Grafik und Sound viele zusätzliche Möglichkeiten und natürlich lagen der Bildschirmspeicher und auch die für BASIC wichtigen Zeropage-Adressen an anderen Stellen im RAM, aber insgesamt war die Umstellung vom CBM auf den C64 nicht problematischer als die vom PET 2001 auf CBM 3001 Series. [Die stellte für Commodore sicher auch keine große Herausvorderung dar, aber ich erinnere mich noch mit Grausen an meine Probleme, denn mir fehlte damals jede Dokumentation.]

Spielanleitung ‘FROSCH’ Szene ‘FROSCH’

Eines der bekanntesten Beipiele für ein umgestelltes Programm ist sicher „FROSCH“ (Original Titel: „Back to Nature„) von der deutschen 1541-Demodiskette [Inhalt und Download]. Wie man an der Spielanleitung noch erkennt, wurde das Spiel ursprünglich für einen CBM-Rechner mit 40-Zeichen-Bildschirm und separatem Ziffernblock geschrieben (Autor: Bob Carr; veröffentlicht im CURSOR Magazine). Außer ein bißchen Farbe hat die C64-Version auch noch ein paar Geräusche bekommen. Doch allein durch einfaches Ändern der in Zeile 0 definierten Bildschirmadresse kann man, mit einigen Abstrichen, das Programm jederzeit auf einem CBM-Rechner ausführen.

Die Portierung von CBM-Programmen auf die Nachfolgegeräte (C64 /C128) hat also eine lange Tradition. Auch von mir gibt es dazu einige vor langer Zeit programmierte Beipiele (Wumpus, Wator). Im Zuge einer 4k BASIC Compo im Forum64 hatte ich mich (im Jahr 2009) des Themas mal wieder angenommen, besaß ich doch noch ein paar simple auf einem CBM 4008 programmierte BASIC-Spielchen auf Diskette, die außer mir noch kein Mensch gespielt hatte. Was lag da also näher, als sich an fertigen Programmen zu bedienen, anstatt sich neue Ideen abzuquälen.

Ich entschied mich damals für die Portierung von „Distichon„. Da noch genügend Bytes verfügbar waren, konnte ich allerdings gleich Nägel mit Köpfen machen und baute das Programm als Multiplattform-Game auf. Neben dem C64 wurden so auch CBM-Rechner (2001, 3001/4001 Series), der CBM 510 (aka P 500) aus der CBM2-Serie und der Plus 4 (C16/C116) bedient. Die bei der Compo noch bestehenden Limitierungen wurden jetzt mit einer Aktualisierung behoben (so dass nun auch die CBM 8001 Serie unterstützt wird).

Ein weiteres BASIC-Spiel (Isola) mit vergleichbarem „Migrationshintergrund“, habe ich für die letztjährigen C128 4kGame Coding Compo erstellt. Vermutlich mangels Teilnehmer ist es aber irgendwie nie zu einer Veröffentlichung der eingereichten Beiträge gekommen. Auch „Isola“ wird zu einem Multiplattform-Game weiterentwickelt. Ähnliches ist auch für das Spiel Canyon-Bomber geplant, das ich für die Compo auf der Bunkerparty 2012 vom CBM 4008 auf C64 portiert hatte (wobei hier zusätzlich einige Assemblerroutinen umzustellen waren).

Langer Rede kurzer Sinn: Im Laufe der Zeit hat sich so einiges an Informationen angesammelt, die es verdienen, hier dokumentiert zu werden. Es soll beleuchtet werden, wie man die einzelnen Rechner identifiziert und welche Besonderheiten zu berücksichtigen sind, wie kompatibel BASIC 2.0 mit sich selber ist, wie zickig sich 40-Zeichen-Bildschirme verhalten können und welche Gemeinheiten sonst noch so lauern. Wenn man all das beachtet, ist es jedoch keine große Kunst mehr ein Programm so aufzusetzen, dass es auf allen 40-Zeichen-Rechnern lauffähig ist.

Teil 1: Identifizieren Sie sich! – Auf welchem Computer läuft mein Programm?
Teil 2: Zeropage, oh, Zeropage – Synopse wichtiger Adressen im RAM
Teil 3: Jedem seine Extrawurst – Das Individuum fordert sein Recht
Teil 4: Immer im Takt – Die CPU (und BASIC): mal schnell, mal langsam
Teil 5: Abwärtskompatibel (zu BASIC 2.0) – Es ist gleich, doch nicht dasselbe
Teil 6: Das vierzigste Zeichen – Wie Fortschritt zum Problem wird

PS: Tokra hat mich darauf aufmerksam gemacht, dass es für den VC 20 einen PET-Simulator mit einer 40-Zeichen-Anzeige gibt. Und natürlich kann auch der VDC im C128 in einen 40-Zeichen-Modus geschaltet werden. Trotzdem werden beide Modi von meinen Multiplatformprogrammen nicht unterstützt. Diese Sonderfälle zu erfassen, würde sicher ein oder zwei Kilobyte zusätzlichen Programmcode erfordern. Da ich die Programme aber so klein halten will, dass sie auch auf einem CBM-Rechner mit nur 8K RAM lauffähig sind, ist das nicht umsetzbar. Was nicht heißen soll, dass es im Einzelfall nicht doch eine Spezialversion für den VDC im C128 geben wird.

Veröffentlicht unter C128, C64, CBM, Soft | Ein Kommentar

Distichon 2012 (Multiplattform Game)

In den letzten Wochen habe ich meinen Beitrag zur 4k BASIC Compo von 2009 übearbeitet und zudem eine Englische Version erstellt. Nach wie vor werden alle Commodore-Rechner mit 40-Zeichen-Darstellung vom PET über CBM 3/4/8001 Series, CBM 510, C16/C116/Plus4 und C64 bis zum C128 unterstützt. Zur Auswahl der gewünschten Sprache wurde ein kleines Vorprogramm erstellt. Die einzelnen Sprachversionen sind aber auch eigenständig lauffähig.

Distichon Sprachauswahl
Das Vorprogramm zur Sprachauswahl, hier auf einem (emulierten) Plus4

Das aktuelle Update behebt auch die Probleme mit den vertauschten Gross- und Kleinbuchstaben im Textzeichensatz des PET 2001 und ermöglicht die Nutzung des Spiels auf einem CBM 8016/8032 durch Umschaltung auf 40-Zeichen-Darstellung. Das Programm kann man auf MySoft128.de als gezipptes D64 downloaden.

Veröffentlicht unter C128, C64, CBM | 2 Kommentare

Tuning-Tips für den C128

Prolog

Mein letzte Beitrag in der Reihe Multiplattform-Programmierung, beschäftigte sich mit der eigentlich simplen Aussage „verwende anstatt FOR…NEXT lieber zeitgesteuerte Schleifen“. Das ganze artete dann aber zu einer Abhandlung über Geschwindigkeitsunterschiede bei Commodores 8-Bittern aus. Um mich nicht noch weiter zu verzetten, klammerte ich das Thema C128 mit 1,3 MHz, also die Möglichkeit im 40-Zeichenmodus im oberen und unteren Rahmen den Prozessor in den 2 MHz-Modus zu schalten, aus. Das erschien mir dann doch als etwas zu spezifisch und sollte später kurz in einem separaten Beitrag, zusammen mit anderen Möglichkeiten des „Tunig“ beim C128, abgehandelt werden.

Wider erwarten hat sich dieses Thema als noch komplexer erwiesen als vermutet und hat mich die letzten 14 Tage mit Recherche, Programmierung und Austesten beschäftigt. Und noch immer ist kein Ende in Sicht. Heute gibt es daher erstmal nur Vergleichsdaten zu den immer mal wieder empfohlenen Tuning-Methoden. Eine tiefergehende Analyse zum Thema „1,3 MHz“ wird später folgen.

Das Herz des Commodore 128: die CPU MOS 8502
Das Herz des Commodore 128: die CPU MOS 8502 (hier mit Anschlüssen zur SuperCPU)

Speed me up Scotty!

Als Nutzer eines Commodore 128 muss man es zähneknirschend akzeptieren, dass dieser Rechner im 40-Zeichen-Modus unter BASIC geschwindigkeitsmäßig gegen jeden C64 „abstinkt“. Da, wenn der VIC für die Bildschirmanzeige zuständig ist, nur eine Taktrate von 1 MHz gefahren werden kann. Die Gründe sind bekannt: Speicherbankumschaltung, komplexeres BASIC und komplexerer Interrupt für Grafik-, Sprite- und Audiofunktionen. All das fordert seinen Tribut und der ist mit „Taktzyklen“ zu bezahlen.

Um ein paar Prozent Geschwindigkeitssteigerung herauszukitzeln (oder auch nur ein paar Promille), gibt es drei mehr oder weniger allseits bekannte Tricks. Es handelt sich um einen sehr massiven und zwei kleinere Eingriffe in das Interrupt-Geschehen.

Ein paar Promille

Einen Hauch von Geschwindigkeitssteigerung erhält man, wenn man das Grafik-Flag manipuliert. Über die Speicherstelle $D8 (216) wird der jeweilige Grafikmodus definiert. Im Grunde mach der Befehl GRAPHIC nichts anderes, als hier einen, dem jeweils gewählten Grafikmodus entsprechenden Wert einzutragen. Die eigentliche Umschaltung zwischen Text- und Grafikmodus erfolgt dann in der Rastervergleichs-IRQ-Routine ($C194). Schreibt man nach der Wahl des gewünschten Grafikmodus mittels POKE216,255 den HEX-Wert $FF in den Speicher, wird ein Teil dieser Interruptroutine nicht ausgewertet.

Der Beschleunigungseffekt beträgt gut 0,4% oder eben 4 Promille. Wird der Befehl GRAPHIC erneut verwendet, überschreibt er diese Manipulation wieder. Man kann den Trick allerdings nicht mit einem Splitscreen-Grafikmodus (GRAPHIC 2 oder GRAPHIC 4) kombinieren, da der übersprungene Teil der Routine genau diese Funktion steuert.

Wenige Prozente

Etwas massiver und auch geringfügig lohnender ist die komplette Deaktivierung der Interruptsteuerroutine für Grafik und Ton ($A84D), auch BASIC-Interrupt genannt. Hier werden die Spritebewegungen gesteuert, Kollisionen und Photonengriffel (Light Pen) ausgewertet und die Befehle PLAY und SOUND abgearbeitet. Wer eigene SID-Abspielroutinen verwenden will, kommt um die Deaktivierung dieser Funktionen sowieso nicht herum. Das Abschalten erfolgt durch Löschen des zugehörigen Steuerbits (Bit 0) in der Speicherstelle $0A04 (2564). Da der Normalwert $C1 (193) ist, erledigt man das mit einem POKE2564,192.

Der Beschleunigungseffekt dieser Maßnahme beträgt etwa 2,7%. Es ist geradezu erschütternd! Die beiden Effekte sind gleichzeitig einsetzbar und summieren sich zu atemberaubenden 3,2%! Genug der Ironie. Wer wirkliche Beschleunigung sehen will, muss massiver werden.

Der Griff zum Hammer

Die in unserem Land wohl bekannteste Routine zur Beschleunigung findet sich im 64er-Sonderheft 22, Seite 51. Das Progrämmchen heißt „C128-FASTER“ und installiert einen Patch für die Interruptroutine, der im oberen und unteren Rahmenbereich des Bildschirms den 2 MHz-Modus aktiviert. Kleiner Nebeneffekt: durch die Veränderung der Interruptroutine sind Splitscreen-Grafikmodi nicht mehr möglich.

Der Beschleunigungseffekt durch“C128-FASTER“ beträgt 26%, was einer mittleren Taktrate von 1,35 MHz entspricht. Eine Kombination mit dem Promilletrick ist wirkungslos, da die Grafikmodeumschaltung in etwas abgespeckter Form jetzt Teil des Patchs geworden ist. Der Prozenttrick wirkt jedoch auch hier additiv. Der „Speedfaktor“ liegt dann bei fast 28%, was einer gefühlten Taktrate von 1,38 MHz entspricht.

Epilog

Tuning Methode Umsetzung Effekt Anmerkung
Raster-IRQ verkürzen POKE216,255 0,4 % Splitscreen-Grafik nicht mehr möglich
BASIC-Interrupt aus POKE2564,192 2,7 % Kein SPRITE, PLAY und SOUND
2 MHz im Rahmen an “C128-FASTER” 26 % Splitscreen-Grafik nicht mehr möglich

Mit der Beschleunigung im oberen und unteren Bildschirmrahmen auf 2 MHz erreicht der C128 unter BASIC (und im 40-Zeichen-Modus) eine Verarbeitungsgeschwindigkeit, die gerade mal so der des C64 entspricht. Allerdings ist nur BASIC so massiv von der Komplexität des C128 betroffen. Programme in Assembler, die eigene Interruptroutinen ein- und das BASIC-ROM ausblenden, können die Geschwindigkeitsvorteile des „1,3 MHz-Modus“ hingegen voll ausspielen.

Veröffentlicht unter C128, Soft | Schreib einen Kommentar

MPP4: Immer im Takt

Schneller, höher, weiter, lautet die Maxime im Sport. Schneller, bunter, klangvoller, könnte man das auf Computer übertragen. Für die Multiplattform-Programmierung kann sich das allerdings als (kleines) Problem erweisen, z.B. wenn man mit einfachen FOR-NEXT-Warteschleifen arbeitet. Der heutige Beitrag in dieser Reihe widmet sich dem „schneller“, wobei man sich in einem Irrtum befindet, wenn man meint, dass neuere 8-Bit-Rechner schneller als ältere gewesen sein müssen, und dem „Schleifenproblem“ (was uns wieder mit den spezifischen Eigenheiten der Rechner konfrontieren wird).

Die CPU: mal schnell, mal langsam

Grundsätzlich wird die Rechengeschwindigkeit durch den Takt des Prozessors (der CPU) bestimmt. Der ist je nach Rechnertyp mal schneller, mal langsamer. Vom C64 weiß man, dass schon zwischen einem NTSC- und einem PAL-Gerät merkliche Unterschiede bestehen. Ein Plus/4 taktet (scheinbar) schneller, ein C128 (ohne VIC-Bildschirmanzeige) ebenfalls. Doch der CPU-Takt ist nur die halbe Wahrheit und manchmal führt er uns auch an der Nase herum.

Tabelle 1: Vergleich der CPU-Taktraten der Commodore-Rechner:

Computer PET/CBM VC 20 P 500 C 64 Plus/4 C 128 1MHz C 128 2MHz
PAL 1 MHz 1,10 MHz 0,98 MHz 0,98 MHz 1,76 MHz 0,98 MHz 1,97 MHz
NTSC 1 MHz 1,02 MHz 1,02 MHz 1,02 MHz 1,79 MHz 1,02 MHz 2,04 MHz

Anmerkungen:
PET/CBM: der Takt ist unabhängig vom Videochip und daher gibt es kein PAL oder NTSC.
VC 20
: Kein Fehler! Die PAL-Version ist schneller.
P 500
: Die verfügbaren Quellen sprechen alle nur von 1 MHz; da jedoch ein VIC II verbaut wurde, ist zu vermuten, dass die gleichen Werte wie für den C64 gelten.
Plus/4: Die hohe Taktrate (hier gibt es aus unterschiedlichen Quellen leicht variierende Angaben) führt in die Irre. Im sichtbaren Bereich des Bildschirms wird auf halbe Taktrate zurückgeschaltet, da TED und CPU sich den Systemtakt teilen müssen. Die effektive mittlere Taktrate liegt wohl irgendwo bei 1 MHz. Wegen unterschiedlicher Anzahl von Bildern/Sekunde zeigt die mittlere Taktrate eine weitere Abhängigkeit von der jeweiligen Videonorm (PAL/NTSC).

BASIC: weniger ist manchmal mehr

Bei Multiplattform-Programmen ist die Geschwindigkeit des BASICs entscheidend. Diese ist von zusätzlichen Faktoren abhängig, die sich durchaus stärker als die Variatonen in der Taktrate auswirken können. Zum einen spielt die Komplexität des Interpreters eine gewichtige Rolle. Ein mächtigeres BASIC (wie beim C128 BASIC 7.0) verlangsamt die Ausführung, spezielle Implementierungen von Grundfunktionen wie die verbesserte Garbage Collection ab BASIC 4.0 beschleunigt Programme mit vielen Stringoperationen. Zum anderen spielt die Komplexität der Hardware eine Rolle. Beim C64 braucht sich der Interpreter nicht groß mit Bankswitching herumzuschlagen, beim C128 hat das jedoch durchaus einen spürbareren Einfluss. Auch beim P500 wirkt sich das komplizierte Bankswitching geschwindigkeitshemmend aus.

Für einen Praxistest verwenden wir folgendes Programm:

10 t1=ti:fori=1to10000:next:t2=ti
20 print (t2-t1)/60"sekunden"

Zur Erinnerung: Die reservierte Variable TI gibt die Zeit in sechzigstel Sekunden (1/60) an. Der Zähler für TI wird initialisiert (auf Null gesetzt), wenn der Rechner startet und auch jedesmal wenn man die Anweisung TI$="000000" ausführt. TI$ gibt die seit dem letzten Initialisieren vergangene Zeit in Stunden, Minuten und Sekunden an („hhmmss“).

Mir ist klar, dass eine einfache Schleife nicht die ganze Wahrheit über die Leistungsfähigkeit eines Rechners offenbart. Es handelt sich mit Absicht um einen simplen Vergleich. Ich tröste mich damit, dass er auf jeden Fall besser ist als ein Vergleich mit PRINT-Operationen, da dabei die zusätzlichen Berechnungen für das Setzen des Farbrams die Ergebnisse einseitig beeinflussen würden.

In Ermangelung der erforderlichen Hardwarevielfalt wurden alle Messungen mit dem Emulator VICE unter Win98 durchgeführt. Daher sind die Angaben mit Vorsicht zu genießen. Zudem zeigten sich in Einzelfällen Probleme mit dem Emulator, die einen eigenen Artikel wert sind.

Tabelle 2 und 3: Zeitverbrauch der FOR-NEXT-Schleife mit 10.000 Durchläufen:

Computer PET 2001 CBM 3032 CBM 4032 B CBM 4032 CBM 8032
Dauer [Sekunden] 9,25 s 9,22 s 9,45 s 10,83 s 11,40 s

Anmerkung: Die Messungen für PET 2001 und CBM 3032 mussten mit VICE 2.2 statt der aktuellen Version 2.4 durchgeführt werden, da VICE 2.4 bei diesen Rechnern eine Bildwiederholrate von 56 fps statt 50 fps anzeigt und folglich andere Berechnungszeiten als VICE 2.2 liefert.

Computer P 500 VC 20 C 64 Plus/4 C 128 (2 MHz)
PAL 15,4 s 9,38 s 11,20 s 13,55 s 15,92 s (7,62 s)
NTSC 10,20 s 10,87 s 17,98 s 15,52 s (7,33 s)

Anmerkung: Für den P 500 sind derzeit keine Angaben zu NTSC möglich, da die Umstellung auf NTSC unter VICE 2.4 dazu führt, dass der Emulator nur noch mit 87%iger Geschwindigkeit läuft, dies beeinträchtigt die Messung. Unter VICE 2.2 ist im Menü keine Auswahl zwischen PAL und NTSC vorhanden. Beim Plus/4 ist deutlich der Effekt der Videonorm zu erkennen. Durch die höhere Bildfrequenz (60 Hz) unter NTSC wirkt sich der Bremseffekt des TED stärker aus als unter PAL (50 Hz). Beim C128 ist zum Vergleich zusätzlich der Wert für den 2 MHz-Modus in Klammern angegeben.

Für Experten sei noch angemerkt, dass der C128 auch im 40-Zeichen-Modus mit ein paar Tricks auf ca. 1,3 MHz beschleunigt werden kann. Die Schleife braucht dann ca. 11,74 s (PAL). Man kann auch noch den BASIC-IRQ deaktivieren und weitere Millisekunden gewinnen, Aber das alles bringt den C128 nur in die Nähe der Geschwindigkeit eines C64.

Kurze Zwischenbilanz: Komplexität und verrotztes Design (Plus/4) lassen die neueren Rechner gegenüber den alten CBMs alt aussehen. Hier gilt: weniger ist mehr. Die Unterschiede in der Effektivgeschwindigkeit sind erheblich. Blinkeffekte oder Anzeigezeiten für Info-Texte sollte man daher nicht mit einer einfachen FOR-NEXT-Schleife lösen!

Der Turbo: schlimmer geht immer

Wer jetzt noch meint, man könne diese „leichten“ Variationen in der Geschwindigkeit ignorieren, der sollte bedenken, dass es noch andere Gründe gibt, es nicht zu tun. Die passenden Stichworte sind SuperCPU, Chameleon im Turbo-Mode und BASIC-Compiler!

Die Zeit: ein steter Fluss

Die Lösung des Warteschleifenproblems ist simpel (oder auch nicht, wie wir später sehen werden) und nicht neu! BASIC 2.0 liefert uns seit seinen Anfängen das Werkzeug, das wir dazu brauchen: TI

Beispiel 1: Eine simple Warteschleife, wie sie vielleicht für einen Blinkeffekt genutzt werden könnte:
for i=1 to 1000 : next i

Auf einem C64 erhalten wir eine Verzögerung von ca. einer Sekunde. Der C128 benötigt für die gleiche Schleife allerdings gute 1,5 Sekunden. Derartige Abweichungen sind, vorsichig ausgedrückt: „unschön“.

Immer exakt eine Sekunde liefert hingegen dieses Programmschnipsel:
10000 t=ti+59:fori=0to1:i=-(ti>t):next:return

Man kann das auch so schreiben:
10000 t=ti+60:fori=0to1:i=-(ti=>t):next:return

So geht’s noch eleganter:
10000 t=ti+60:fori=-1to0:i=ti<t:next:return

Für einen relativen Vergleich der Rechnergeschwindigkeiten kann man ermitteln, wie häufig eine Schleife durchlaufen wird. Dazu baut man einen Zähler ein. Integriert man weitere Elemente in die Schleife kann man so auch die verbleibenden Ressourcen abschätzen. Zur Demonstration mag sich die simple Schleife selbst genügen. Die nachstehende Tabelle basiert auf folgendem Programm:

10 x=0:t1=ti:t=ti+60:fori=-1to0:i=ti<t:x=x+1:next:t2=ti
20 print (t2-t1)/60"sekunden", x"loops"

Computer CBM 3032 CBM 4032 VC 20 C64 Plus/4 (NTSC) C128 (2 MHz)
Schleifen-durchläufe 162 140 157 131 124 (96) 102 (212)

Anmerkung: Die Zahlen gelten bei den farbfähigen Computern für die PAL-Geräte. Zum Vergleich ist beim Plus/4 zusätzlich der Wert für NTSC, beim C128 der für den 2 MHz-Modus, in Klammern angegeben.

Beispiel 2: Eine Warteschleife mit Abbruchoption, wie sie vielleicht für die Anzeige von Infotexten genutzt werden könnte. Das folgende Unterprogramm kombiniert elegant Zeitschleife und Tastaturabfrage:

10000 rem 10 sekunden textanzeige (weiter mit <taste>)
10010 t=ti+600:fori=-1to0:getg$:i=(ti<t)and(g$=""):next:return

Über TI läßt sich auch bei Spielen der zeitliche Verlauf steuern, indem (z.B.) Unterprogramme (nur) alle halbe Sekunde angesprungen werden und nicht, abhängig von anderen Operationen und dem jeweiligen Rechnertyp, häufiger. Der Schwierigkeitsgrad des Programms ist dann plattformunabhängig gleich. Wobei man zugeben muss: gleich schwach, denn der schwächste Rechner bestimmt dann das zulässige Tempo. Was nerven kann, wenn es sich um interpretiertes BASIC handelt.

Beabsichtigt man hingegen, die Programme zu compilieren (danach ist das jeweils compilierte Programm natürlich wieder systemspezifisch, aber man braucht es nur in einer Version zu pflegen), dann ist ein TI-gesteuertes Programm oft die einzige Möglichkeit es überhaupt noch spielen zu können.

Der Frust: Commodore ist eben Commodore!

Commodore wäre nicht Commodere, wenn sie nicht wieder die simpelsten Grundregeln mißachtet und Blödsinn fabriziert hätten. Zum Thema TI/TI$ muss es daher heißen: Achtung Falle! Man mag es sich nicht vorstellen, was in den Knallköpfen damals vorgegangen sein muss, als man sich entschloß die CBM II-Reihe mit einem BASIC auszustatten, dass die Systemvariable TI (TIME) nicht mehr kennt.

Zwar zeigt der P 500 ein BASIC 4.0 an (es ist allerdings Version 4.7), das zu BASIC 2.0 abwärtskompatibel sein soll, doch hilft das wenig. TI ist nicht verwendbar und TI$ (TIME$) erhielt (wohl als schwachen Ersatz) einen veränderten Wertebereich. Was die Sache noch schlimmer macht. In BASIC 2.0 ist TI$ sechsstellig (ti$=“000000″) im Format „hhmmss“ (Stunden, Minuten, Sekunden). Bei BASIC 4.7 kommt eine siebte Stelle hinzu. Diese steht für Zehntel Sekunden. Kürzere Zeiteinheiten sind in BASIC nicht mehr erfassbar.

Bei der im Abschnitt „BASIC: weniger ist manchmal mehr“ in Tabelle 3 angegebenen Rechenzeit habe ich daher gemogelt. Statt des oben angegebenen Programms habe ich das folgende verwenden müssen (und folgerichtig habe ich keine zweite Nachkommastelle angegeben, denn es gab hier nichts zu Runden):

10 ti$="0000000":fori=1to10000:next:t$=ti$
20 print val(right$(t$,3))/10+val(mid$(t$,3,2))*60"sekunden"

Doch was bedeutet das für die Multiplattform-Programmierung? Man muss entweder auf den hübschen TI-Trick verzichten, für den P 500 eine alternative „Schleife“ auf Basis von TI$ entwickeln oder den P 500 aus dem Kreis der unterstützten Rechner ausschließen (da waren’s nur noch vier: PET/CBM, C64, Plus/4, C128). Beim Verbreitungsgrad des P 500 fällt da im Zweifel die Entscheidung leicht. Doch ein Gutes hat die Sache: Spötter können die CBM II-Reihe jetzt als zweifelsfrei „zeitlos“ titulieren – und in Anbetracht des Designs, wäre in diesem Spruch sogar noch eine zweite Wahrheit verborgen.

Nachdem sich, sozusagen als Nebenprodukt dieses Beitrags, die erste der bereits angekündigten bösen Überraschungen offenbart hat, mag man erahnen, dass im nächten Teil weiteres Ungemach droht, wenn wir uns intensiver mit der Kompatibilität bezüglich BASIC 2.0 beschäftigen werden.

Veröffentlicht unter C128, C64, CBM, Soft | Schreib einen Kommentar

MPP 3: Jedem seine Extrawurst

Nachdem im letzten Teil dieser Serie über Multiplattform-Programmierung die über die gemeinsame Basis BASIC 2.0 hinausgehenden, vergleichbaren Eigenschaften der Commodore-Rechner im Mittelpunkt standen und Wege gesucht wurden, diese auf den unterschiedlichen Geräten einheitlich anzusprechen, geht es diesmal um Beispiele für die Nutzung spezifischer, individueller Eigenschaften. Diese zu kennen und zu berücksichtigen, ist oft hilfreich und in manchen Fäller sogar erforderlich. Auch der CBM-Checker macht Gebrauch davon.

Einige dieser Besonderheiten beziehen sich auf Befehle aus höheren BASIC-Versionen (BASIC 4.0, 4.7, 3.5 und 7.0). In diesen Fällen ist es erforderlich, dass die betroffenen Programmzeilen nur vom passenden Rechnertyp abgearbeitet werden. Erschwerend kommt hinzu, dass die Token, also die Verschlüsselung der zusätzlichen Befehle, für die BASIC-Versionen 4.x und 3.5/7.0 unterschiedlich und daher inkompatibel sind. In einer späteren Folge werden wir uns mit einem solchen Fall noch beschäftigen müssen. Hier aber sollen nur das Befehlspaar FAST und SLOW und das Kommando GRAPHIC 0 des C128 betrachtet werden.

Commodore 128: Die Kombination SLOW:GRAPHIC 0 findet sich auch im Programm CBM-Checker. Sie soll sicherstellen, dass das Programm, wenn es im 80-Zeichen-Modus gestartet wurde, in den 40-Zeichen-­Modus wechselt und dort angezeigt wird. Es kann auch durchaus mal sinnvoll sein, für den Fall längerer Berechnungen, auf einem C128 die Möglichkeit zu nutzen, den Rechner kurzzeitig mit FAST in den 2 Mhz-Modus zu versetzten. Es gibt kein Gesetz, das das verbietet.

Andere Besonderheiten beziehen sich auf spezielle Zeropage bzw. I/O-Adressen. Einige davon sind uns schon im Programm CBM-Checker begegnet. Hier sollen nun die und eine weitere näher betrachtet werden.

CBM 4001/8001 Series: Mittels PEEK(224) unterschiedet man zwischen einem CBM-Rechner mit 40-Zeichen (PEEK(224)<>0) und mit 80-Zeichen (PEEK(224)=0) Bildschirmbreite. Diese Information kann genutzt werden, um ein spezielles Programm (CBM4032 ANY HZ) nachzuladen, das die erforderlichen Einstellungen vornimmt, um den Bildschirm in den 40-Zeichen-Betrieb umzustellen und diese Änderung in das Betriebssystem einzubinden. Durch diesen Trick können viele Spiele für einen CBM 40xx auch auf einem CBM 80xx laufen.

PET 2001 / CBM 3001 Series: Ein bekanntes Beispiel für systemspezifische Eigenschaften ist der Killer-Poke, auch Fastprint-Poke genannt. Diesen sollte man aus bekannten Gründen nie auf CBM-Rechner mit dem neuen Universalboard (board#3) und CRTC-Chip anwenden. Andererseits laufen ältere CBM-Rechner mit altem Board (board#2) ohne ein gesetztes Bit 5 an Adresse 59458 ($E842; VIA) wie eine Schnecke. Das fragliche Bit wird mittels POKE59458,PEEK(59458)OR32 gesetzt.

YouTube: Killer poke! (PET 2001)
Killer poke! (PET 2001): Ein ziemlich sinnfreies Video, aber ein schöner Totenkopf

PET 2001: Ein paar hübsche Blinkeffekte aber auch ein sauberes „Umschalten“ von Bildschirminhalten erhält man mit dem Blank-Poke (Adresse 59409, Bit 3; $E811; PIA 1) . Um den Bildschirm auszuschalten verwendet man POKE59409,52 mit POKE59409,60 läßt sich der Bildschirm wieder einschalten. Dieser POKE-Befehl funktioniert nur bei einem PET 2001 (board#1) und schaltet den Bildschirm komplett ab. Das Programm Distichon nutzt diesen Effekt, um unbemerkt die Darstellung des Einleitungstexts korrigieren zu können. Bekanntlich sind beim PET 2001 im Zeichensatz Groß- und Kleinschriftzeichen vertauscht. Dies wird in besagtem Programm unsichtbar durch eine kleine Assemblerroutine korrigiert.

PET/CBM: Während man bei den farbfähigen Commodore-Rechnern zwischen den zwei implementierten Zeichensätzen bequem über Steuerzeichen umschalten kann [Groß-/Kleinschrift: PRINT CHR$(14); Grafikzeichen: PRINT CHR$(142)], muss dies bei PET/CBM mittels POKE-Befehl bewerkstelligt werden. POKE59468,14 aktiviert Groß-/Kleinschrift und POKE59468,12 den Grafikzeichensatz.

Plus/4, C16, C116: Bedingt durch die Speicherkonfiguration überlagern sich RAM-Bank und ROM-Bank. Da anders als beim C128 kein BANK-Befehl verfügbar ist, wird über Adresse 1177 ($0499) gesteuert, auf welche Speicherbank ein PEEK-Befehl zugreift. Nach einem POKE1177,62 liest PEEK aus dem ROM, nach POKE1177,63 (Grundeinstellung) aus dem RAM. CBM-Checker benutzt diesen Trick, um an den für die Systemerkennung benötigten IRQ-Vektor zu kommen.

Mit den gesammelten Informationen sollte es jetzt eigentlich möglich sein, ein Multiplattform-Programm zu erzeugen. Dass da aber trotzdem noch ein paar interessante Kniffe und (böse) Überraschungen warten, wird sich in den folgenden Teilen dieser Serie zeigen.

Nachtrag (22.12.2012) : Zusammenfassung

Funktion Computer Code
Umschaltung auf 40-Zeichen Commodore 128 SLOW:GRAPHIC 0
Test auf 40/80-Zeichen CBM 4001/8001 PEEK(224) [0:80 / >0:40 Zeichen]
Killer-Poke / Fastprint-Poke PET 2001/CBM 3001 POKE59458,PEEK(59458)OR32
Blank-Poke (Bildschirm aus/an) PET 2001 POKE59409,52 / POKE59409,60
Zeichensatzumschaltung
(Kleinschrift/Grafik)
PET/CBM POKE59468,14 / POKE59468,12
Speicherzugriff (PEEK auf ROM/RAM) Plus/4, C16, C116 POKE1177,62 / POKE1177,63
Veröffentlicht unter C128, C64, CBM, Soft | 3 Kommentare

MPP 1: Identifizieren Sie sich!

Der Erste Schritt bei der Multiplattform-Programmierung besteht im Erkennen des Computersystems. Denn bei aller Ähnlichkeit zwischen den Commodore 8-Bit-Rechnern, gibt es doch genügend Unterschiede, die es zu beachten gilt. Zur Unterscheidung sind spezifische und unverwechselbare Kriterien heranzuziehen. Ein Beispiel für eine automatische Rechnererkennung ist die Routine die sauhund im Forum64 gepostet hat.

Wenn man auf Details, wie den RAM-Ausbau beim VC20 oder die Unterscheidung zwischen C16 und Plus4 verzichten kann, geht es aber auch einfacher. Statt diverse Adressen zu prüfen, genügt es, sich auf eine zu beschränken, die bei allen Rechnern unterschiedlich ausfällt aber bei allen ROM-Varianten identisch ist. Eine vertiefende Analyse läßt sich dann in den erforderlichen Fällen noch nachträglich durchführen.

Am Ende des ROMs finden sich gleich zwei geeignete Kandidaten für einen Rechnercheck. Nach meinen bisherigen Recherchen sind IRQ- (Puls) und RESET-Vektor bei jedem Commodore-Rechner unterschiedlich jedoch für verschiedene ROM-Versionen eines Rechners immer identisch. Zur Identifizierung genügt es, das Low-Byte des Vektors zu prüfen. Ich persönlich bevorzuge dabei den IRQ-Vektor, für irgendetwas muss man sich ja mal entscheiden.

Computer IRQ LB (hex) LB (dez) RESET LB (hex) LB (dez)
PET 2001 $E66B $6B 107 $FD38 $38 056
CBM 3001 $E61B $1B 027 $FCD1 $D1 209
CBM 4001/8001 $E442 $42 066 $FD16 $16 022
P 500 / CBM 500 $FBE5 $E5 229 $F99E $9E 158
CBM 600 / 700 $FBD6 $D6 214 $F997 $97 151
VC 20 $FF71 $72 114 $FD22 $22 034
C 64 / C64 SX $FF48 $48 072 $FCE2 $E2 226
C 16 / C 116 / Plus 4 $FCB3 $B3 179 $FF6F $F6 246
C 128 / C 128 D $FF17 $17 023 $FF3D $3d 061

Tabelle der Systemvektoren IRQ und RESET für alle Commodore-8-Bit-Rechner

Der IRQ-Vektor liegt bei $FFFE/FFFF, der RESET-Vektor bei $FFFC/FFFD im ROM; wie bei der CPU 6502 üblich im Format LSB/MSB (Low-Byte/High-Byte bzw. LB/HB). Mittels PEEK lässt sich der gewünschte Wert auslesen. PEEK(65534) liefert das Low-Byte des IRQ-Vektors, PEEK(65532) den des RESET-Vektors. Beim Commodore Plus 4 (und C16 / C116) muss zuvor allerdings noch das ROM eingeblendet werden, was einen kleinen schmutzigen Trick erfordert. Man kann ihn in Zeile 130 des nachfolgenden Listings finden:

100 rem *** cbm checker a (wte) ***
110 :
120 cbm=peek(65534): pet=0: c$=“commodore “
130 if peek(1177)=63 then poke1177,62: cbm=peek(65534): poke1177,63
140 rem 2001,3001,4001,p500,cbm600/700,vc20,c64,c16/p4,c128
150 restore:data 107, 27, 66, 229, 214, 114, 72, 179, 23
160 ix=0: for i=1 to 9: read a:if a=cbm then ix=i: i=9
170 next: on ix gosub 240, 260, 280, 340, 360, 380, 400, 420, 440
180 if ix then 460
190 print
200 print „not supported system!“
210 print „dieser computer wird nicht unterstuetzt!“
220 end
230 :
240 a$=“2″: goto300
250 :
260 a$=“3″: goto300
270 :
280 a$=chr$(52-(peek(224)=0)*4)
290 :
300 if a$<„4“ then poke59458,peek(59458) or 32:rem killer poke (fast poke)
310 a$=mid$(„pet cbm „,5+(a$=“2″)*4,4)+a$
320 pet=59468: c$=c$+a$+“001 series“: return
330 :
340 c$=c$+“p500/cbm510″: return
350 :
360 c$=c$+“600/700 series“: return
370 :
380 c$=c$+“vic20/vc20″: return
390 :
400 c$=c$+“64″: return
410 :
420 c$=c$+“c16/c116/plus4″: return
430 :
440 c$=c$+“128″: graphic 0: slow: return
450 :
460 print chr$(147)chr$(142): if pet then poke pet,12
470 print „this program is running on a“
480 print c$: print
490 print „dieses programm laeuft auf einem“
500 print c$: print: end

Variante A der Systemerkennung. Rechnerspezifische Details werden über ON / GOSUB definiert

100 rem *** cbm checker b (wte) ***
110 :
120 cbm=peek(65534): c$=“commodore “
130 if peek(1177)=63 then poke1177,62: cbm=peek(65534): poke1177,63
140 restore
150 rem 2001,3001,4001,p500,cbm600/700,vc20,c64,c16/p4,c128
160 data 107, pet 2001 series, 1, 1, 0
170 data 27, cbm 3001 series, 1, 1, 0
180 data 66, cbm 4001 series, 1, 0, 0
190 data 229, p500/cbm510, 0, 0, 0
200 data 214, 600/700 series, 0, 0, 0
210 data 114, vic20/vc20, 0, 0, 0
220 data 72, 64, 0, 0, 0
230 data 179, c16/c116/plus4, 0, 0, 0
240 data 23, 128, 0, 0, 1
250 :
260 ix=0: for i=1 to 9
270 read a, a$, pet, kp, c128
280 if a=cbm then ix=i: i=9
290 next
300 if ix then 370
310 :
320 print
330 print „not supported system!“
340 print „dieser computer wird nicht unterstuetzt!“
350 end
360 :
370 if kp then poke59458,peek(59458) or 32:rem killer poke (fast poke)
380 if kp<>pet then if peek(224)=0 then a$=“cbm 8″+mid$(a$,6)
390 c$=c$+a$: if c128 then graphic 0: slow
400 :
410 print chr$(147)chr$(142): if pet then poke 59468,12
420 print „this program is running on a“
430 print c$: print
440 print „dieses programm laeuft auf einem“
450 print c$: print: end

Variante B der Systemerkennung. Rechnerspezifische Details werden über DATA-Statements definiert

Wer den Quellcode genau studiert, wird feststellen, dass für die Rechner der CBM 8000er Reihe, die den gleichen IRQ-Vektor haben wie die 4000er, eine zusätzliche Detailprüfung implementiert wurde. Über die Speicherstelle $E0 (224) in der Zeropage kann man leicht erkennen, welchen Rechner (8001 Series: 0 / 4001 Series: 128) man vor sich hat.

Beide Varianten der Rechnererkennung haben ihre Vor- und Nachteile und stehen hier nur beispielhaft für zwei Möglichkeiten das Problem anzugehen [die Programme können als Text- und PRG-Dateien (gezippt) für Testzwecke heruntergeladen werden]. Da sich meine Multiplattform-Programme in der Regel auf die Rechner mit 40-Zeichen-Darstellung beschränken, lasse ich in der Praxis die Erkennung von CBM 600/700 und VC 20 „unter den Tisch fallen“ und erkläre sie zu „nicht unterstützten Systemen“. Und natürlich muss der Identifizierung auch eine ausgefeilte Differenzierung folgen (hier angedeutet durch den „Killer-POKE“ und die BASIC 7-Befehle GRAPHIC und SLOW). Doch dazu berichte ich später mehr.

Veröffentlicht unter C128, C64, CBM, Soft | Ein Kommentar

Canyon Bomber 65%

Cracker sind auch nicht mehr das, was sie mal waren. Ein für mich vollkommen neues Erlebnis haben mir die zwei Lahmer von Really Proud Lamers beschert. Immerhin benennen Sie sich passend. Mein Beitrag zur C64 Mixed-Compo der Bunkerparty, Canyon Bomber 65%, wurde binnen kürzester Zeit „gecrackt“!

Canyon Bomber 65% als ‘gecrackte’ Version

Die „Leistung“ der Cracker bestand darin, die deutschen Texte irgendwie ins Englische zu übersetzen und das ganze zu einem One-Filer zu verbinden. Großartig. Ich weiß jetzt nur noch nicht so recht, ob ich mich beleidigt oder geehrt fühlen soll. Beleidigt, weil sowas als „Crack“ bezeichnet wird (seit wann kann man freie Software cracken?) und geehrt, weil jemand das Spiel für Wert hält, übersetzt zu werden.

Wie auch immer, vielleicht kann ich sogar ein paar Worte dieses Machwerks für meine eigene Übersetzung verwenden. Schließlich soll ja auch dieses Spiel irgendwann als zweisprachige Multiplattform-Version (CBM, C64, C128, Plus4) veröffentlicht werden.

Veröffentlicht unter C64, Compo | Schreib einen Kommentar

4k BASIC Compo (Forum64)

Heute endet die Einreichungsfrist für die 4k BASIC Compo im Forum64. Die Regeln: C64, Floppy 1541, Joysticks und maximal 4096 Bytes BASIC-Programm. Das seltsame bei diesen Wettbewerben ist, dass man erst nicht weiß, was man programmieren soll. Dann erscheinen 4096 Bytes doch recht viel (das will erstmal eingetippt werden). Und kurze Zeit später sucht man verzweifelt im Programm herum, wo man die paar noch zusätzlich benötigten Bytes einsparen könnte. Mal ganz zu schweigen davon, das völlig ungeklärt bleibt wo man die Zeit für das Programmieren hernehmen soll.

Ich habe es mir daher etwas leichter gemacht und aus meiner „Schatzkiste“ uralter Programme etwas ausgebuddelt, was ich vor Urzeiten für meinen CBM 4008 programmiert hatte. Ein bißchen Farbe reingeklatscht, ein wenig Optimierung im Programmablauf, ein paar Fehler eliminiert und fertig war Distichon 2009, mein Beitrag zu 4k Compo. Warum ich das Spiel Distichon genannt habe, weiß ich heute leider auch nicht mehr. Genausowenig kann ich mich erinnern, wo ich die Spielidee abgekupfert habe. 25 Jahre sind halt eine lange Zeit…

Die Spielregeln sind einfach und werden im Programm angezeigt. Ein Stapel Plättchen muß ungleichmäßig geteilt werden. Stapel mit einem oder zwei Plättchen werden daher gelöscht. Zwei Spieler (einer davon kann der Computer sein), ziehen abwechselnd. Wer den letzten Zug macht, hat gewonnen. Das ist alles.

Distichon (Multiplattformspiel)

Da das Spiel die erlaubten 4096 Bytes nicht ausfüllte, habe ich eine kleine Computer-Erkennungsroutine eingebaut. Dadurch ist das Programm auf folgenden Systemen lauffähig: C64 (Abbildung links oben), C128 [40-Zeichen-Modus] (rechts oben), C16, C116, Plus4 (links unten), PET 2001, CBM 3001 Series, CBM 4001 Series (rechts unten) und CBM 510. Wenn man das Spiel auf einem CBM 8001 Series laufen lassen möchte, muß zuvor mit dem Programm „CBM4032 ANY HZ“ eine 40-Zeichen Darstellung aktiviert werden. Alles was keinen 40-Zeichen-Bildschirm hat (z.B. CBM 6×0, CBM 7×0, VC 20 und KIM 1) wird vom Programm weder korrekt erkannt noch unterstützt.

Auf farbfähigen Systemen stehen vier Farbschemata zur Verfügung, die durch „Zufall“ selektiert werden. Nur „Classic Green“ und „Blue Ocean“ sehen auf einem Emulator immer gut aus. „Grey Malve“ gibt eigentlich nur auf einem Plus4 ein hübsches Bild, da hier andere Farben als auf einem C64 verfügbar sind. Das vierte Farbschema, „Red Lemmon“, ist seinerseits stark von der Monitoreinstellung bzw. im Emulator von der verwendeten Farbpalette abhängig. Das Ergebnis schwankt dabei zwischen ganz nett und ziemlich gruselig.

Da die alten CBM-Rechner keinen Verschiebelader haben, wurde das Programm mit der Startadresse $0401 gespeichert. Auf einem C64 muss es also mit LOAD "dateiname",8 und nicht mit LOAD "dateiname",8,1 geladen werden. Als weitere Besonderheit ist der Killer-Poke, der die Textausgabe auf PET und CBM-Rechnern mit alten Boards beschleunigt, zu erwähnt. Dieser wird auf einem CBM-System (nur) dann aktiviert, wenn der Rechner nicht als CBM 4001 Series erkannt wird. Sollte also jemand auf einem neuen Board ein altes CBM-Betriebssystem laufen haben, könnte es mit dem Bildschirm Probleme geben. Dafür wird jede Haftung ausgeschlossen.

Nachtrag 01.04.2009:
Download des Programms via Forum64

Veröffentlicht unter C128, C64, CBM, Compo | Ein Kommentar