Archiv der Kategorie: C128

Einzeiler (update)

Auf Commodore128.org wurden gestern Neuigkeiten zur “One Liners Competition” veröffentlicht. Leider wurde dabei das ursprüngliche Posting gelöscht, so dass der Link in meinem ersten Blog-Beitrag zu diesem Thema ungültig wurde. Der offizielle Start der Competition wird voraussichtlich in der nächsten Ausgabe der Commodore Free bekannt gegeben. Einsendeschluß für Beiträge soll Freitag, 8. März sein.

Die erlaubte Programmzeilenlänge ist nicht auf die von den jeweiligen Bildschirmeditoren direkt unterstützte Länge von 80 bzw. 160 Zeichen begrenzt; tricksen ist durchaus zulässig. In den Speicher gepokter und mit SYS gestarteter Maschinencode wird ebenfalls akzeptiert, reine Assemblerprogramme jedoch nicht. Beispiele kann man sich auf der jetzt als Diskimage veröffentlichten Beispieldiskette ansehen, die ich der Einfachheit halber hier als gezipptes File bereitstelle.

Muster vom Cover des Buchs: “10 PRINT CHR$(205.5+RND(1)); : GOTO 10″

Veröffentlicht unter C128, C64, CBM, Compo | 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

Nachlese 2012

Im Laufe des Jahres haben sich einige Meldungen angesammelt, die es nie in den Blog geschafft haben. Sei es, weil der aktuelle Bezug nicht (mehr) gegeben war, sei es, weil das Thema nicht genug hergab oder ich keine Lust hatte es auszurecherchieren. Manches davon verdient jedoch zumindest eine Erwähnung. Daher folgen jetzt hier: Meldungen, die es nicht in mein Blog geschafft haben:

Januar 2012: Megabit 128 Function ROM
Genaugenommen hätte man schon im November oder Dezember 2011 über diese Erweiterung für Sockel U36 im C128 schreiben können, aber ich wollte ja einen Bericht über mein eigenes Exemplar verfassen. Bis auf zwei Randnotizen hier im Blog, ist daraus jedoch nichts geworden. Vielleicht im nächsten Jahr…

Februar 2012: Digital Audio Concepts
Ebenfalls schon seit Herbst 2011 hatte Vanessa in ihrem kleinen Hardware Shop eine 1 MB REU und ein Stereo-SID-Modul im Angebot. Darüber gelesen hatte ich im Februar. Den geplanten Beitrag kann ich mir jetzt aber endgültig sparen, denn der Shop wurde inzwischen geschlossen.

März 2012: ACE128TOS
Irgendwann im Frühjahr stieß ich auf der Commodore News Page von Richard Lagendijk auf einige ältere Berichte zu ACE128. Diese neue Betriebssystem mit GUI, das den VDC als Standardbildschirm verwendet und von einer SuperCPU profitiert (diese aber nicht voraussetzt) wird von Miroslav Karkus und einigen Mitstreitern programmiert. Seinen besonderen Reiz erhält es durch die VDC-Grafikfähigkeiten, für die Dirk Vroomen verantwortlich zeichnet. Die Entwicklung geht weiter und ich halte mich auf dem Laufenden, aber im Augenblick ist das Ganze doch noch ziemlich pre-Alpha.

ACE128TOS About-Screen

Juni 2012: BioTerror!
Was sich anhört wie eine akute Warnung vor einem kommenden Terroranschlag ist zum Glück nur ein neues Strategiespiel für den Original PET 2001, angekündigt auf CommodorePETAlive. Weitere Infos finden sich auf der Webseite des Entwicklers.

Juli 2012: Media Player 128 (beta)
Auf Commodore128Alive posted Hydrophilic diverse Infos über das PC-Tool CBM Encoder, das Videos in ein spezielles Format für den Media Player 128 umwandelt. Dieser Mediaplayer für den Commodore 128 läuft sowohl im 40- als auch im 80-Zeichen-Modus (Video werden aber nur auf dem 40-Zeichen-Bildschirm [VIC II] angezeigt), kann verschiedene Sound- und spezifische Videoformate abspielen und unterstützt NTSC und PAL. Weitergehende Infos finden sich auf den Webseiten des Entwicklers.

August 2012: Retroport
Irgendwann im Sommer bin ich auf Retroport gestoßen. Und damit auf eine der wohl umfangreichsten Dokumentationen zu Commodore „Krempel“ (Werbeartikel und anderes mit dem Commodore-Logo), die mir je begegnet ist. Diese Sammlung braucht den Vergleich mit den entsprechenden Seiten beim Commodore Billbord nicht zu scheuen.

Oktober 2012: Whacky-Wit
Im Oktober bekam ich ein Mail, ob ich nicht im Blog über das Retro-Style-Brettspiel „Whacky-Wit“ berichten wolle. Nun, das hatte ich mir schon vor dem Mail überlegt und mich dann wegen der fehlenden acht Bit dagegen entschieden. Pac-Man ist ja nun nicht gerade ein Commodore-spezifisches Spiel. Andererseits ist es ein wirklich schönes Projekt. Daher hier der Hinweis: Whacky-Wit kann man jetzt käuflich erwerben.

Whacky-Wit

November 2012: Windows 105
Bei Recherchen zu Hardsync kam mir auf Hack a Day ein anderer Beitrag unter die Finger. Ein 13jähriger programmierte sich im Jahr 2002 sein eigenes Windows… für den C64. Das Vorbild war Microsoft Windows 95. Die Versionsnummer für den CeVi wurde einfach „hochgezählt“. So entstand Gigasoft Windows 105.

Dezember 2012: Avalanche & Mayhem
Zwei neue „kommerzielle“ Spiele für Commodore CBM (CBM 3001/4001/8001 Series) und auch den VC 20 erblickten das Licht der Welt: Avalanche und Mayhem. Publisher ist Revival Studios. Die Vollversion wird auf einer Daten-Kassette geliefert. Man kann die Spiele aber auch frei herunterladen. Es sind diverse weitere Veröffentlichungen für 2013 geplant.

Anmerkung: Ergänzt und überarbeitet am 1. Januar 2013

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

Einzeiler

Das Magazin Commodore Free beabsichtigt eine „One Liners Competition“ für BASIC 2.0, 3.5 und 7.0 zu starten. Alle Commodore Acht-Bit-Rechner vom PET bis zum C128 sind „startberechtigt“. Es wird zwei Hauptkategorien (und jeweils mehrere Unterkategorien) geben: Echte Einzeiler und Zweizeiler. Wobei sich „Zweizeiler“ so definiert, dass alle Variablen-, DATA- und Funktionsdefinitionen in einer und die eigentliche Programmlogik in der anderen Zeile stehen.

Eine offizielle Ankündigung der Competition, mit Bekanntgabe der genauen Regeln, wird es im kommenden Jahr im Heft #67 der Commodore Free geben. Zusätzlich sollen einige Programmbeispiele auf Heftdiskette (D64-Image) veröffentlicht werden. (Quelle: Commodore128.org)

Es gab vor ein paar Jahren schon mal eine (wenig ergiebige) Competition für Einzeiler für den Commodore 128. Hoffen wir, dass der jetzt geplante Wettbewerb mit verbreiterter Plattform ergiebiger wird.

Das Buch: “10 PRINT CHR$(205.5+RND(1)); : GOTO 10″

Einzeiler kennt man aus dem Handbuch zum C64 und aus alten Computerzeitschriften. Dass man mit diesem Thema auch ein ganzes Buch füllen kann, haben Nick Montfort und seine Co-Autoren im November diesen Jahres mit der Veröffentlichung von „10 PRINT CHR$(205.5+RND(1)); : GOTO 10“ bewiesen. Der arg seltsam anmutenden Titel stammt von einem Programmierbeispiel aus dem Handbuch zum C64 und erzeugt auf dem Bildschirm das auch im Cover (siehe Abbildung) verwendete Muster.

Auf über 300 Seiten werden von verschiedenen Autoren die Themen Einzeiler (verschiedene Varianten), Blockgrafik, Commodore C64, BASIC als Programmiersprache, Zufallszahlen, Irrgärten und Computer-Kunst bearbeitet. Das englischsprachige Buch ist in gedruckter Form im Handel erhältlich. Über die Homepage 10print.org ist zudem eine kostenlose PDF-Version herunterladbar.

Veröffentlicht unter C128, C64, CBM, Compo | Ein 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 2: Zeropage, oh, Zeropage

Unlängst habe ich über Möglichkeiten zur Unterscheidung verschiedener Commodore-Rechner geschrieben. Heute geht es darum, diese Informationen zu nutzen, um Programme entwickeln zu können, die sich unterschiedlicher Hardwarebasis anpassen können. Für die weiteren Beschreibungen beschränke ich mich auf die 8-Bit-Rechner mit 40-Zeichen-Darstellung (PET, CBM, P500, C64, Plus4, C128), da ansonsten der Aufwand für die Anpassung der Bildschirmdarstellung zu groß wäre bzw. die Darstellungsmöglichkeiten zu stark einschränken würden.

Unabhängig von später zu behandelnden Sonderfällen, die durch individuelle Eigenheiten oder spezifische Inkompatibilitäten einzelner Rechnertypen ausgelöst werden, gibt es einige Unterscheidungsmerkmale, die alle (oder zumindest mehrere) Rechner betreffen und die im Programm am Besten über das Vorbelegen einer Variable mit einem jeweils systemspezifischen Wert gelöst werden müssen. Ich nenne das jetzt hier einfach mal eine Systemvariable. Was sich hier kompliziert anhört, wirkt in einem Beispiel ganz simpel und verständlich: Anstatt mit POKE 1024,0 im linken oberen Bildschirmeck eines C64 einen Klammeraffen erscheinen zu lassen, verwendet man eine Variable: P=1024 und einen flexiblen POKE-Befehl: POKE P,0. Durch Anpassen des Werts der Variable P für verschiedene Systeme kann der POKE-Befehl auf allen Rechnern im linken oberen Eck den gewünschten Klammeraffen erzeugen.

Neben dem Basiswert des Bildschirmspeichers könnten auch Werte für I/O-Register als Systemvariable interessant sein, um zum Beispiel die Hintergrund- und Rahmenfarbe festlegen zu können:

Computer Screen-RAM Color-RAM Hintergrundfarbe Rahmenfarbe
PET 2001 32768
CBM 3/4/8001 Series 32768
P 500 / CBM 500 53248 54272 55329 55328
C 64 / SX 64 1024 55296 53281 53280
C16 / C116 / Plus 4 3072 2048 65301 65305
C 128 / C 128 D 1024 55296 53281 53280

Eine weitere Spielwiese ist die Belegung der „Zeropage“. Bei Commodore-Rechnern ist die Besonderheit zu beachten, dass mit dem Begriff Zeropage oft die „erweiterte Zeropage“, also der Bereich bis $03ff (beim C128 sogar bis $12ff), angesprochen wird und nicht nur die Zeropage, wie sie die CPU sieht. Und so soll der Begriff auch hier verstanden werden. Wobei klar sein muss, dass der Begriff „erweiterte Zeropage“ technisch gesehen Unsinn ist. Möglicherweise hat Commodore (oder eigentlich Microsoft) diesen Begriff dadurch provoziert, dass beim ROM-Update vom PET 2001 zu den Rechnern der CBM 3001 Series diverse Kernel- und BASIC-ROM-Variable und -Zeiger aus der Zeropage in den Bereich ab $0200 bis $033a verlegt wurden und umgekehrt. In jedem Fall war ein Begriff für den Gesamtbereich des von Kernel und BASIC benötigten RAM-Speichers erforderlich.

In der (erweiterten) Zeropage finden sich Daten zur zuletzt genutzten Peripherie (Gerätenummer für Nachladeoperationen), zu Tastatureingaben (Tastaturpuffer und Zeiger in den selben), Sprungektoren, z.B. für den IRQ, und vieles mehr. Die nachfolgende Tabelle listet einige dieser Daten in einer synoptischen Darstellung für die hier betrachteten Geräte auf:

Label PET 2001 CBM 3/4/8001 P 500 C 64 Plus 4 C 128
FA 241 212 159 186 174 186
NDX 525 158 209 198 239 208
STKEY 521 155 169 145 145 145
KEYD 527 623 939 631 1319 842
SFDX 515 151 205 203 198 212
LSTX 547 166 225 215 2038 213
SHFLAG 516 152 (224) 653 1347 211
RPTFLG (228) 650 1344 2594
PNT 224/225 196/197 200/201 209/210 200/201 224/225
PNTR 226 198 203 211 202 236
TBLX 245 216 202 214 205 235
IIRQ 537/538 144/145 768/769 788/789 788/789 788/789
TBUFFR 634/826 634/826 (1024) 828 819 2816

FA: Aktuelle Gerätenummer – Diese Adresse ist relevant für alle Programme, die andere Programmteile nachladen. So können Kassetten- und Diskversionen unterschieden werden und das Nachladen erfolgt immer vom richtigen Laufwerk.

NDX: Anzahl der Zeichen im Tastaturpuffer (Warteschlange) – Durch Beschreiben mit dem Wert Null (0) wird der Tastaturpuffer „gelöscht“.

KEYD: Tastaturpuffer – In der Regel umfasst der Tastaturpuffer 10 Zeichen.

STKEY: Flag für STOP-Taste – Bei einigen Rechnern kann hier auch die RVS-Taste abgefragt werden. Prinzipiell stehen die 8 Bits für 8 Tasten. Welche das sind, ist jedoch systemspezifisch (abhängig von der Verdrahtung der Tastaturmatrix); nur die STOP-Taste ist immer dabei.

SFDX: Nummer der augenblicklich gedrückten Taste – In der Regel systemspezifische Indexnummer in die Tastaturdekodiertabelle. Bei CBM-Rechnern mit neuen ROMs, neuem Board und CRTC-Chip (40xx/80xx) ist es allerdings der dekodierte PETSCII-Code. Wer es in VICE testen will, kann dazu den 4032 (neue ROMs) mit dem 4032B (alte ROMs) vergeichen.

LSTX: Nummer der zuletzt gedrückten Taste – Analog zu SFDX.

SHFLAG: Flag für SHIFT-Taste – Neben der SHIFT-Taste werden hier (sofern vorhanden) auch die Tasten CONTROL und COMMODORE durch ein Bit repräsentiert. Beim P 500 beeinflussen auch andere Tasten den Inhalt dieser Speicherzelle.

RPTFLG: Ermöglicht Tastenwiederholung – Dieses Flag bestimmt die Art der Repeatfunktion: $80 = aktiv für alle Tasten, $40 = keine Tasten, $00 nur für Cursorsteuerung. Bei den CBM-Rechnern hat nur der CBM 80xx eine Repeatfunktion. Beim P 500 konnte ich das Flag nicht zweifelsfrei identifizieren.

PNT: Zeiger auf aktuelle Zeile (Text) – Pointer auf den Zeilenanfang.

PNTR: Aktuelle Cursor-Spalte

TBLX: Aktuelle Cursor-Zeile

IIRQ: IRQ-RAM-Vektor – Über diesen Vektor werden eigene Interruptgesteuerte Routinen eingebunden.

TBUFFR: Kassettenpuffer – Immer wieder beliebt für kleine, unterstützende Assemblerroutinen.

Üblicherweise werden nur wenige der hier aufgeführten Systemvariablen in die Systemerkennungsroutine integriert werden. Dafür kommen noch ein paar systemspezifische Systemadressen hinzu, die jeweils nur für ein Rechnersystem relevant sind, um dort Sonderfunktionen auslösen bzw. steuern zu können. Darüber wird allerdings erst im nächsten Teil berichtet.

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

Commodore 128 Sticker

Durch reinen Zufall bin ich die Tage über ein Ebay-Angebot für Commodore 128 Case Badge Sticker gestolpert. Verkäufer war Hardware-Shuttle, ein Ebay-Shop für „Commodore Amiga – C64 – Apple & more“.

Commodore 128 Case Badge Sticker

Ich habe mir gleich mal zwei der Sticker zusenden lassen. Das hat auch problemlos funktioniert (wie man an der Abbildung sieht) . Auch wenn inzwischen (30. Oktober) von den bei Ebay angebotenen Stickern mehr als die Hälfte verkauft wurden, darf man wohl davon ausgehen, dass der Vorrat noch lange nicht erschöpft ist. Auf der Homepage findet man neben dem C128-Sticker auch noch den bekannten Commodore-Sticker (Chickenhead-Logo), mehr als nur eine Variante eines C64-Stickers und einen C128 D-Sticker. Zumindest von letzterem muss ich mir jetzt unbedingt gleich noch ein paar zusenden lassen …

Nachtrag 05.11.2012: Die C128 D-Sticker sind nun auch angekommen, wie man sieht:

Commodore 128 D Case Badge Sticker

Veröffentlicht unter C128 | Schreib einen Kommentar

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

Commodore 128 D Black Edition!

Ich bin eigentlich kein Freund von „gemoddeten“ Commodore-Rechnern. Die meisten Versuche beleidigen entweder mein ästhetisches Empfinden oder erregen meinen Widerwillen gegen mutwillige Zerstörung von Originalhardware. Wenn jedoch ein umgebauter Rechner ordentlich verarbeitet und gestylt wurde, zolle ich dem gern Respekt.

Was allerdings unlängst im Forum64 der Öffentlichkeit präsentiert wurde, löste eine andere Reaktion aus. Ich musste schnell zum nächsten Spiegel rennen, um zu überprüfen, ob mein Gesicht nicht vielleicht wirklich gelb angelaufen war… aus purem Neid! DerSchatten hatte dort einen mit hoher Präzision gemoddeten Commodore 128 D präsentiert, der nicht nur mir solch starke Emotionen abrang.

Commodore 128 D Black Edition!

Für den C128D SD2IEC/LCD Black Edition! wurde als Basis ein C128 D (kein DCR) verwendet, da dieser für den Einbau eines Parallelspeeders (hier ProfDOS) besser geeignet ist. Der Umbau enthält zusätzlich ein SD2IEC-Interface (Shadowolf-Variante) das an der Front montiert wurde. Dazu musste das Netzteil um einige Zentimeter nach hinten versetzen werden. Verbaut wurden außerdem noch eine DualSID-Platine mit 2x6581R5 und ein 64k VDC RAM Upgrade. Eine schwarze Lackierung (matt) und HIFI-Füße runden die edele Optik ab. Detailliertere Infos, auch zu den Elementen an der Frontseite, finden sich im Originalbeitrag im Forum64, auf dem auch dieser Text beruht.

Thumbnail C128D Black Edition (Bild 1) Thumbnail C128D Black Edition (Bild 2) Thumbnail C128D Black Edition (Bild 3)

Alle Bilder sind aus dem Beitrag im Forum64. (c) 2012, DerSchatten

Veröffentlicht unter C128 | Schreib einen Kommentar

Unnützes Wissen (3): Zwiespältiges GETKEY

Nachdem mit dem DATA-Bug und dem LOAD & PEEK-Problem hier zwei Fälle von unnützem Wissen diskutiert wurden, denen man zumindest noch eine klitzekleine Restnützlichkeit attestieren könnte, kann davon beim heutigen Beitrag keine Rede sein. Man muss hier zum besseren Verständnis vorausschicken, dass es das Commodore-BASIC erlaubt, die BASIC-Befehle bei der Eingabe abzukürzen. Dazu wird der Buchstabe (oft ist es der zweite oder dritte), der dem System eine eindeutige Identifizierung des Kommandos erlaubt, „geSHIFTet“ eingetippt. Im Groß-/Kleinschriftmodus sieht das dann z.B. so aus: lI entspricht LIST; renU entspricht RENUMBER und gO entspricht GOTO.

Angeregt durch die Diskussion um den DATA-Bug, hat Hydrophilic im C128-Forum auf Commodore128.org darauf hingewiesen, dass auch zur GETKEY-Anweisung unnützes Wissen existiert. Im C128 System Guide und auch im deutschen C128 Bedienungshandbuch ist für GETKEY getkE als Abkürzung aufgeführt. Das ist nicht die ganze Wahrheit. Hydrophilic offenbarte eine andere Abkürzung: auch gEkE entspricht GETKEY.

Abkürzung für GETKEYWie die nebenstehende Abbildung zeigt, hat er recht. Damit gäbe es zwei mögliche Abkürzungen. Man kann aber genausogut behaupten, es gäbe gar keine. Denn für den BASIC-Interpreter existiert der BASIC-Befehl GETKEY überhaupt nicht!

Man kann GETKEY auch als GET KEY schreiben (was die Abkürzung gEkE bzw. gE kE erklärt). Damit besteht eine gewisse Parallele zu GOTO und GO TO; beide Schreibweisen für den Sprungbefehl sind zulässig. Während jedoch GOTO ein eigenständiger Befehl mit eigenem Token ist, für den es auch eine eigene Abkürzung gibt, gibt es kein Token für GETKEY. Für den Interpreter erscheint GETKEY daher als gespaltene Persönlichkeit mit den Namen GET und KEY und wird mit zwei Token codiert. Dabei ist GET eindeutig das dominante Ego, denn die entsprechende BASIC-ROM-Routine (im C128 ab $5612) behandelt KEY einfach als einen Parameter der GET-Anweisung.

Veröffentlicht unter C128 | Schreib einen Kommentar