online: 1
Rekord: 57

Last update:
2005/04/20

Home
Übergeordnete Seite
Search:
Suche starten
In English, please!

CFX Hacking

Das PICT - Format zur Speicherung von Bild - und Grafikdaten

Der Casio CFX speichert sowohl die Daten von Picture1..Picture6, als auch die Bilddaten des Grafikmodus in diesem Format. Das Besondere dabei ist, dass die Farbinformationen hier schichtweise anstatt Pixel für Pixel vorliegen, wobei pro Pixel für jede Schicht genau ein Bit benötigt wird (Pixel in Schicht an oder aus). Unterschiedliche Farben können sich deshalb auch überlappen: setzt man ein Pixel beispielsweise grün, übermalt es mit orange und löscht die Orangeschicht hinterher wieder, ist das Pixel dann nicht leer, sondern wieder grün.

Dass hat aber mehr Nachteile als Vorteile, denn für 4 Farben werden dann 4 Schichten, also insgesamt 4 Bit anstatt nur 2 pro Pixel benötigt (2² = 4; CGA Grafik verwendet z.B. auch 2 Bit pro Pixel für 4 Farben), d.h., Ein Bild auf dem Casio CFX wäre dann nur 2KB statt 4KB groß (was bei dem knappen Speicher nur recht wäre).

Die 4. Farbe

Bei 4 Farben werden die meisten jetzt denken, dass ich weiß, grün, blau und orange meine - völlig falsch! Weiß wird nämlich nicht durch eine Farbschicht dargestellt, sondern weiß ist ein Pixel dann, wenn alle Farbschichten an der entsprechenden Stelle ausgeschalten sind (weiß ist deshalb auf dem Casio CFX nicht als "Farbe" zu betrachten). Welches ist neben orange, blau und grün dann die 4. Farbschicht? Die Farbe orange².

Zur Farbdarstellung auf dem Casio CFX ist dabei folgendes zu sagen:
  • Orange ist die höchstwertige Farbschicht, die alle anderen Farbschichten überdeckt. D.h., ist diese Farbschicht aktiviert, erscheint das Pixel immer orange, egal ob es zusätzlich blau und / oder grün ist.
  • Danach kommt blau, dass nur von Orange überdeckt wird
  • Grün ist unter den konventionellen Farben orange, blau, grün die niederwertigste und wird sowohl von blau als auch orange überdeckt
  • Als neue Farbe kommt nun orange² hinzu, welche tatsächlich die niederwertigste ist (was man bisher ja eigentlich von grün gedacht hat). Orange² wird auf dem Display farblich genau wie das richtige orange dargestellt, und ändert man den Orangekontrast, ändert sich auch der Kontrast von orange². Der Unterschied ist allerdings, dass orange² sogar von grün überdeckt wird!
Das glaubt ihr nicht !? Dann zieht mal folgende CAT - Datei auf euren Rechner, löscht mit Cls den Grafikspeicher und lasst Picture 1 anzeigen. Was ihr seht sind 5 horizontale Streifen: der erste ist weiß, der zweite orange, der dritte wieder weiß, der vierte noch mal orange und der letzte wieder weiß. Jetzt zeichnet eine vertikale grüne Linie über alle 5 Streifen, und ihr werdet sehen, dass das erste Orange kein gewöhnliches Orange ist! Während die grüne Linie nämlich auf dem ersten orangefarbenen Streifen zu sehen ist, wird sie vom zweiten ordnungsgemäß überdeckt.



Download der CAT-Datei (568 Bytes)


Diese vierte Farbe ist allerdings nicht über den Taschenrechner direkt zugänglich (für orange gibt es das Attribut orange und für grün green, dass man Grafikbefehlen voranstellen kann, für orange² gibt es so was allerdings nicht), und die Konvertierungsprogramme, die CATs ind BMPs umwandeln, unterstützen so etwas auch nicht, weil BMPs nicht im Schichtformat gespeichert sind, sondern die Farbinformation jeweils pixelweise vorliegt (also in der entsprechenden CAT - Datei dann pro Pixel nur eine Schicht aktiviert ist). Außer durch die Manipulation von Backup - Dateien gibt es daher keine Möglichkeit, auf diese 4. Farbe überhaupt zuzugreifen, und sie hat deshalb KEINE praktische Verwendung; hätte Casio dagegen auf eine 4. Farbschicht verzichtet, hätte man immerhin noch 1KB Speicher sparen können (pro Bild würden dann nur 3 - anstatt 4KB benötigt), zumal das Schichtformat beim Displayrefresh ja sowieso pixelweise konvertiert wird, denn das Casio CFX Display selbst verfügt natürlich nicht tatsächlich über 2 orangefarbene LCD Schichten (das ist zumindest stark anzunehmen)!

Der Videospeicher des Casio CFX befindet sich nämlich nicht im RAM, sondern nach jedem Grafikbefehl wie Cls, Circle usw., der den Inhalt der Grafikdaten im RAM ändert, führt der Rechner einen Displayrefresh aus, der diese Daten ausliest, entsprechend konvertiert und an den Grafikadapter des Rechners sendet (hauptsächlich deshalb sind die Grafikbefehle auch nur so langsam).

Ohne Displayrefresh würden Änderungen der Grafikdaten im RAM auf dem Display also überhaupt nicht sichtbar. Aber zurück zum eigentlichen Datenformat:

Der Aufbau des Formats ist wie folgt:

  • Größe: 4KB = 4096 Bytes
  • Bestehend aus 4 Farbschichten zu je 1KB, die im Speicher direkt aufeinander folgen
  • Schichtreihenfolge (von niedriger zu höherer Adresse): orange, blau, grün, orange²

  • 1 Schicht = 128x64 Pixel x 1Bit = 8192Bit = 1KB
  • Eine Schicht ist dabei in 16x64 Sprites zu je 8x1 Pixel unterteilt (1 Sprite ist daher genau 1B groß)
  • Die Sprites sind reihenweise so angeordnet, dass das untere rechte Sprite (Sprite 15;63) innerhalb des 1KB Speichers der Schicht das erste (Sprite #0), Sprite(15;0) Sprite #63 und das obere linke Sprite das letzte im Speicher (Sprite #1023) ist
  • Die Pixel sind innerhalb des Sprites von rechts nach links angeordnet, d.h., Bit 0 ist das Pixel, das am weitesten rechts, Bit 7 das, das am weitesten links liegt.




Der Casio Basic Interpreter führt also folgenden Algorithmus aus, wenn er einen PxlOn y,x - Befehl einliest:

ptr := pctbase + col shl 10 + 1023 - (x and 0F8h) shl 3 - y;
byte (ptr^) := byte (ptr^) or (8 shr (x and 7));
call ROM:DisplayRefresh;
mit pctbase = Startadresse der Grafikdaten, col = Farbindex (0 = orange, 1 = blau, 2 = grün, 3 = orange²) und x;y im Bereich 0;0 .. 127;63.

Folgender Algorithmus entspräche PxlOff x,y:

ptr := pctbase + col shl 10 + 1023 - (x and 0F8h) shl 3 - y;
byte (ptr^) := byte (ptr^) and (not (8 shr (x and 7)));
call ROM:DisplayRefresh;


und PxlTst x,y (führt unnötigerweise ebenfalls einen Displayrefresh aus):

call ROM:DisplayRefresh;
ptr := pctbase + col shl 10 + 1023 - (x and 0F8h) shl 3 - y;
ANS := boolean ((byte (ptr^) and (8 shr (x and 7))) <> 0);

Copyright (C) 2004 by Marco Kaufmann