Am Anfang war das Video von Goodwell (s. rechts).Video: Vorstellung von VDCBasic
Da berichtete der Forum64-User @Goodwell also, dass man mit dem C128 auch auf dem VDC wunderbar farbige Bilder hinkriegen könnte. Und zwar ohne einen größeren Aufwand (z.B. das Aufspüren, Installieren und Erlernen des in Nordamerika sehr erfolgreich gewesenen Basic8, siehe dazu auch bei den GoDot-Savern).
Die einzige nötige Zutat sollte sein: die winzige Basic-Erweiterung VDCBasic von @Mac Bacon (Marco Baye), der auch den allseits bekannten Crossassembler ACME programmiert hat.
Bild 1: Damit fing alles an...
Bild 2: VDC-Bild von GoDot erzeugt
Mithilfe von VDCBasic erzeugte Goodwell auf dem VDC farbige Bilder in der Auflösung 160×100 Pixel (vergrößert auf 320×200 Pixel, s. Bild 1). Das dazu erforderliche Bildformat, wie es im Video beschrieben wird, erinnerte mich sofort an das 4Bit-Bildformat von GoDot und schon war ich alarmiert. Das könnte man doch mit GoDot unterstützen? Gesagt - getan, es entstand der svr.VDCLores für Goodwells C128-Demo-Programm. Jetzt stand diesem Lores-Modus die weite Grafikwelt offen (Bild 2).
Und ich war elektrisiert. Sowas hatte ich mit meinen alten 128ern (die lange schon nicht mehr existieren) nicht hingekriegt. Was, wenn aber jetzt? Und wo kannte ich mich am besten aus? Bei TSB! Eine Verbindung aus TSB und VDCBasic, sollte das funktionieren?
Im C64-Modus lässt sich der VDC des C128 ansprechen, das wusste ich von GoDot. Und mit Interpretern kenne ich mich auch aus, das beweist ja allein TSB. TSB um einen zusätzlichen Interpreter erweitern? Also eine Erweiterung (VDCBasic) einer Erweiterung (TSB) einer Erweiterung (Simons' Basic) schaffen? Irre Idee! Aber sowas liebe ich! Also, nichts wie losgelegt.
Und da haben wir nun VDCBasic TSB!
Die Schlüsselwörter von VDCBasic:
Es gibt 19 neue Befehle, deren Schlüsselwörter meistens aus drei Buchstaben bestehen. Zwei davon sind Funktionen mit einem Rückgabewert. Man kann sie einteilen in Befehle, die sich auf VDC-Register beziehen, Befehle, die den VDC-Speicher verändern und solche, die einen Austausch zwischen VDC und C128/C64 vornehmen.
Registerbefehle: | ||
---|---|---|
Schlüsselwort | Parameter/Argument | Zweck |
RGW | Reg, Wert | Wert in Register schreiben (ReGister Write) |
RGA | Reg, Wert | Register lesen, per AND mit Wert verknüpfen und zurückschreiben (ReGister And) |
RGO (in TSB: RGR) |
Reg, Wert | Register lesen, per OR mit Wert verknüpfen und zurückschreiben (ReGister Or bzw. oR) |
RGD | (Reg) | Register auslesen z.B. PRINT RGD(0) (get ReGister Data) |
SYN | [Reg, Wert [, Reg, Wert...]] | wartet darauf, dass der Bildschirm aufgebaut ist (SYNchronize) und schreibt dann (optional) Wert(e) in Register |
DISP | Adresse | Startadresse des Bitmap-Speichers setzen (DISPlay) |
ATTR | Adresse | Startadresse des Attribut-Speichers setzen (ATTRibut) |
CRSR | Adresse | Startadresse des Cursors im Bildschirmspeicher setzen (CuRSoR) |
RST | Wert | Wert= 1: Reset des VDC (ReSeT) Wert= 2: ROM-Zeichensatz laden (nach $2000) Wert= 3: beides |
Speicherbefehle: | ||
VMW | Adresse, Wert | Wert in Adresse schreiben (Vdc Memory Write) |
VMA | Adresse, Wert | Adresse auslesen, per AND mit Wert verknüpfen und zurückschreiben (Vdc Memory And) |
VMO | Adresse, Wert | Adresse auslesen, per OR mit Wert verknüpfen und zurückschreiben (Vdc Memory Or) |
VMD | (Adresse) | Speicheradresse auslesen z.B. PRINT VMD(0) (get Vdc Memory Data) |
VMF | Adresse, Wert, Zähler | ab Adresse zähler-mal mit Wert beschreiben (Vdc Memory Fill) |
Austauschbefehle: | ||
RTV | C64-/C128-Adresse, VDC-Adresse, Zähler | ab C64-/C128-Adresse Zähler Bytes nach VDC-Adresse kopieren (Ram To Vdc) |
VTR | VDC-Adresse, C64-/C128-Adresse, Zähler | ab VDC-Adresse Zähler Bytes nach C64-/C128-Adresse kopieren (Vdc To Ram) |
VMC | VDC-Adresse1, VDC-Adresse2, Zähler1 [, Zähler2 [, Add2Target [,Add2Source)]]] |
von VDC-Adresse1 Zähler1 Bytes zu VDC-Adresse2 kopieren [das Ganze zähler2-mal durchführen [und dabei Add2Target zu VDC-Adresse2 addieren [und Add2Source zu VDC-Adresse1]]] (Vdc Memory Copy; alle Parameter in [..] optional) |
SWP | VDC-Adresse, C64-/C128-Adresse, Zähler | ab VDC-Adresse Zähler Bytes mit C64-/C128-Adresse austauschen (SWaP) |
VCC | C64-/C128-Adresse, VDC-Adresse, Zähler | ab C64-/C128-Adresse einen Zeichensatz im Umfang von Zähler Bytes nach VDC-Adresse kopieren (Vdc Charset Copy). Der Parameter Zähler wird allerdings nicht beachtet und intern auf 2048 gesetzt (für 256 Zeichen) |
Programme, die in VDCBasic geschrieben wurden, sind zwischen C128 (Basic 7) und C64 (TSB) austauschbar. Das Schlüsselwort RGO/RGR passt sich beim Laden automatisch an. | ||
Ein paar grundsätzliche Programmierschnippsel
Das Wichtigste zuerst, VDCBasic laden und installieren:
1200 proc vdcbasic 1210 x=peek($d030) and 3: if x then print at(2,2)"No VDC found, exiting."at(22,0)"";:end 1220 if d!peek($7900)<>31145 then do 1230 print at(2,2)"Loading VDCBasic TSB..." 1240 scrld def $79,7,1,3:scrld 1,dd,3,"ext.vdcbasic":scrld restore 1245 data 52,55,4e,0d 1250 reset 1245:for i=$0277 to $027a:read x$:poke i,nrm(x$):next:poke 198,4 1255 print at(4,2)"done. "at(6,2)"";:sys $7900 1260 done 1265 end proc
Erläuterung:
· Zeile 1210 testet über das VIC-Register $D030 (zuständig für den FAST-Modus des C128), ob das Programm überhaupt auf einem C128 läuft. Wenn ein Wert ungleich Null zurückgeliefert wird, sind wir nicht auf einem C128 (dann gibt es keinen VDC) und das Programm wird beendet.
· Zeile 1220 testet, ob VDCBasic vielleicht schon installiert wurde. Wenn ja, muss es nicht noch einmal geladen werden.
· Die Zeilen 1230 und 1240 laden VDCBasic in den Speicher
· Die Zeilen 1245 bis 1255 aktivieren VDCBasic und starten das Programm neu.
Dann das Zweitwichtigste, den VDC in einen kontrollierten Ausgangszustand versetzen:
RST 1:VMF 0,0,2048:VMF $0800,15,2080: REM Den VDC in den Standard-PAL-80-Zeichen-Textmodus versetzen und Text- und Attributspeicher löschenoder
RST 3:VMF 0,102,2048:VMF $0800,15,2080:REM wie 1, aber zusätzlich den ROM-Zeichensatz rekonstruieren
In TSB wird bei RST 2 (und 3) der C64-ROM-Zeichensatz in den VDC übertragen (der sich allerdings nicht vom Zeichensatz des C128 unterscheidet). Für einen eigenen Zeichensatz lädt man diesen zunächst in den C64-Speicher und schreibt ihn dann mit VCC $4000, $2000, 0 in den VDC (die Null ist ein obligatorischer Dummy, die hier gewählten Adressen sind Beispiele, $2000 ist die Default-Speicherposition des VDC-Zeichensatzes). Das Zeichen 102 ist ein Schachbrettmuster.
Und drittens die monochrome Bitmapgrafik einschalten
RGO 25,128: RGA 25,255-2^6: RGO 28,2^4: RGW 36,0
Erläuterung:
· Bit 7 in Register 25 schaltet die Bitmapgrafik ein (wenn 1)
· Bit 6 in Register 25 schaltet das Attribut-RAM (die Farben) aus (wenn 0)
· Bit 4 in Register 28 teilt dem VDC mit, dass er auf 64 KB zugreifen kann (wenn 1)
· die Null in Register 36 erzwingt die maximale Refeshrate für die Speicherchips
Hinweis: In TSB lautet der Befehl RGO aus Interpretergründen RGR. Beide erhalten aber das gleiche Token und sind im Programmmodus daher identisch. Abgespeicherte reine VDCBasic-Programme sind unter den Plattformen austauschbar.
Beispiele
Alle Beipiel(programm)e befinden sich auf der VDCBasic-TSB-Demo-Diskette! 1) Zuerst ein Beispiel für den Textmodus des VDC. Die Anzeige ist normalerweise im 80-Zeichenmodus (kann man aber umstellen) und wird mit dem ROM-Zeichensatz dargestellt. In unserem Beispiel sieht man jedoch den modifizierten Retrofan-C64-Zeichensatz "thin.set" (Bild 3, siehe auch Titelbild dieser Webseite, und hier auf dem C64 "in Aktion" in einer TSB-Anwendung).
Bild 3: 80-Zeichen-Bildschirm vom C64 aus!
Der Code zum Einlesen eines eigenen Zeichensatzes sieht so aus:
1100 proc zeichensatz 1110 if d!peek($4000)<>$4200 then do 1120 scrld def $40,8,1,3:scrld 1,dd,3,"thin.set":scrld restore:vcc $4000,$2000,2048 1130 if d!peek($4000)<>$4200 then do 1140 print at(2,2)"";:error:print at(2,2)"Kein 'thin.set', nehme ROM set." 1145 rs=$80:bg=102:z$="dem C64-ROM-Zeichensatz" 1150 rst 2 1160 done 1170 print at(4,2)"done." 1180 done 1185 convert 1190 end proc
Eine sinnvolle Anwendung für ein verschachteltes IF..THEN DO: Zeile 1110 checkt, ob der Zeichensatz bereits geladen wurde (dann passiert gar nichts), und Zeile 1130 prüft, ob er nun (direkt nach dem Laden, Z. 1120) im Speicher steht. Wenn nicht, gibt es eine Fehlermeldung und es wird (per RST 2) auf den Alternativzeichensatz aus dem ROM ausgewichen. Nebenschauplatz: CONVERT (Z. 1185, Routine hier nicht abgedruckt) stellt die Rahmenzeichen für den Befehl INSERT, mit denen das Programm umgeht, für den jeweiligen Zeichensatz sicher.
2) Das zweite Beispiel zeigt, wie man farbige Bilder auf dem VDC anzeigen kann. Dazu wird ein Modus verwendet, der ziemliche Ähnlichkeit mit dem CGA-Lowres-Modus aus der PC-Welt hat. In diesem Video geht der Urheber dieses ganzen Projekts, Goodwell, näher darauf ein.
Bild 4: Ein Amica-Paint-Bild auf dem C128!
Bild 5: Farben bis zum Abwinken!
1300 proc vdcinit 1310 rst 3:rgw 0,127:rgw 4,155:rgw 9,1:rgw 6,100:rgw 7,125 1320 rgo 25,128:rgo 28,16:rgw 36,0 1350 ap=16000:vmf 0,15,ap:vmf ap,0,8000 1370 attr ap 1380 end proc
Vor allem die Zeile 1320 sorgt für den Grafikmodus (Register 25, Bit 7: Grafik an, Reg. 28, Bit 4: VDC hat 64 KB). Register 9 beschränkt die Höhe einer Farbzelle auf zwei Rasterlinien (Wert: 1) und Register 6 legt fest, dass es davon 100 Stück geben soll. Fehlen nur noch Register 1, mit dem die Darstellungsbreite eingestellt wird: 80 (ist durch den RST-Befehl geschehen) und das Bereitstellen von Pixeln, mit denen die Farbzellen ihren Sinn erhalten. Das geschieht mit dem ersten VMF-Befehl in Zeile 1350. Er füllt (VMF 0,15,ap) die Bitmap mit identischen (2×2-) Pixeln. Der andere initialisiert lediglich den Farbbereich, der dann später mit "Leben" versorgt werden soll (aus den nachzuladenden Dateien mit den Farbwerten). Wir haben also einen Modus, der auf einer Fläche von 320×200 Pixeln ein Bild in der Auflösung 160×100 Pixel in Farbe darstellt (siehe Bilder).
Hinweis: Wenn man ein VDC-Basic-Programm in TSB editiert, muss man statt RGO den Befehl RGR verwenden, da RGO vom Basic-V2-Interpreter beschädigt werden würde und nicht funktionstüchtig wäre.
3) Das dritte Beispiel bezieht sich auf das Video vom Anfang dieser Seite. Dort geht es darum, dass man auch auf dem VDC eine richtige Spielwelt erstellen kann, deren Orte durch waagerechtes und senkrechtes Scrollen erreicht werden können. Man kann also an Orte gelangen, die nicht auf dem Anfangsbildschirm einer Welt zu sehen sind. Im Video zeigt Goodwell eine Szene aus Space Quest Chapter 1 und scrollt dort in den Gängen hin und her. Wie man sieht, geht das auch mit VDCBasic TSB:
Allerdings hat uns hier schon die Speicherenge des C64 (zumal unter TSB) zu schaffen gemacht. Das C128-Programm, das die Screenshots aus dem Spiel in VDC-Bilder überführt (bei den Materialien zum Video oben als Download dabei), bedient sich des großen zuammenhängenden Speichers des C128 (es braucht 48 KB am Stück).
Wir auf dem C64 verwenden dazu GoDot, für das es einen speziellen Saver für VDC-Lowres-Bilder gibt. Er kann sowohl die in Beispiel 2 besprochenen 160×100-Bilder herstellen als auch Bilder über mehrere Bildschirme (320×100 Pixel, erzeugt auf 640×200-Untergrund) wie das Space-Quest-Bild hier oben. Bedienungshinweise findet man auf der eben genannten Seite zum GoDot-Saver.
Die Disk
Auf der unten zum Dowload stehenden Disk befinden sich folgende Programme
(die mit dem Kürzel ".dmo" sind TSB-Programme, die mit dem Kürzel ".c128" sind deren Basic7-Vorlagen):
vdctext.dmo | Hier wird der VDC nur als Textausgabebildschirm von TSB, allerdings im 80-Zeichenmodus, betrieben. Das Programm installiert dazu einen eigenen Zeichensatz im VDC und verwendet diesen. Der ausgegebene Text liegt im Demo-Programm im PETSCII-Format vor und wird von einer kurzen PROC-Routine in den erforderlichen Bildschirm-Code umgewandelt. |
vdc160x100.dmo (vdclores2.c128) |
Lädt und zeigt das Bild "vdclores.dat" (s. Bild 1, oben auf dieser Seite). In Zeile 1105 kann das Bild gewechselt werden, indem man dort einen anderen Namen einträgt. Auf Disk befinden sich noch: "landscape.vdc" und "ghostbusters.vdc". Das letztgenannte hat der GoDot-Saver VDCLores (auch auf der Disk) mithilfe von Halve erstellt (Bild 2). |
vdc320x100.dmo | Dieses Demo zeigt die alternativen 320×100-Bilder des Savers VDCLores an. Voreingestellt ist das Bild "enidblyton" (eine Illustration aus dem Buch "Die Insel der Abenteuer", eingescannt von GoDot). Es besteht aus zwei Einzeldateien ("enidblyton1.vdc" und "enidblyton2.vdc"), deren individuelle Namen (die Nummerierungen) beim Speichern automatisch erzeugt werden. Auch beim Laden muss man nur den eigentlichen Namen per Zuweisung vorgeben (in Programmzeile 1005). Auf Disk bedinden sich drei weitere Bilder: · "kingsquest4" (ein Screenshot des DOS-Spiels) · "jane" (ein Scan eines Tarzan-Comics von Hal Foster) · "spacequest1" (das ist der Screenshot, den Goodwell in seinem Video vorführt: aus Space Quest 1 für DOS) |
horizontal.dmo (horzdemo.c128) |
Hier zeigt Goodwell, wie man mit den VDCBasic-Befehlen auf einfache Weise Effekte auf dem VDC erzeugen kann, u.a. ein Hin- und Herscrollen des VDC-Bildschirms. |
vertikal.dmo (btscroll.c128) |
Hier wird ein monochromes Bild der Größe 512×720 Pixel ("btpic", ein Screenshot der Mac-Version von Bard's Tale im BMP-Format) auf- und abgescrollt. Auch das kommt in Goodwells Video vor. |
transition.dmo (lowtransit.c128) |
Schön anzusehen: der klug programmierte Übergang zwischen zwei Bildern auf dem VDC. |
|
|
ext.vdcbasic | Das ist die TSB-Version der VDC-Basic-Erweiterung. Wie man sie einbindet, steht hier weiter oben. Sie residiert an Position $7900 und verkleinert damit den freien Basic-Speicher um 1792 Bytes. Alle besonderen Erweiterungen von TSB tragen das Präfix ext. (für Extension) |
vdcbasicac6.bin | Und das ist die ursprüngliche C128-Version von Marco Baye. Diese hier läuft an Position $0AC6 im C128. |
thin.set | Dies ist eine dünnbeinige Version des besser lesbaren C64-Zeichensatzes von Forum64-User @Retrofan. |
svr.VDCLowres | Mit diesem GoDot-Modul erzeugt man beliebige 320×200 Pixel große Bilder in der Auflösung 160×100 Pixel. Es enthält einen weiteren Modus für 640×200 Pixel große Bilder, die auf dem VDC besonders dargestellt werden müssen (siehe die Demoprogramme oben). |
|
Die restlichen Disketten-Einträge sind die schon erwähnten Bilder. Und hier die Disk:
Download VDCBasic TSB (als D64-Datei)