Das Betriebssystem des ST beinhaltet viele Routinen, mit denen man die FĂ€higkeiten des Rechners erst richtig nutzen kann. Die Routinen des Betriebssystems, sei es BIOS, XBIOS oder GEMDOS, sind sehr leistungsfĂ€hig und fĂŒr einige Programmieraufgaben fast unumgĂ€nglich. Sie sollen deshalb hier nĂ€her vorgestellt und analysiert werden.
Höhere Programmiersprachen enthalten solche Systemaufrufe meist nicht im Sprachstandard, da diese bei jedem Rechner bzw. Betriebssystem unterschiedlich sind. Beim ST gibt es aber trotzdem eine Möglichkeit, Systembefehle (TOS & GEM) aufzurufen.
Grundprinzip
Bevor eine Betriebssytemroutine aufgerufen werden kann, muĂ sie zuerst deklariert werden. Dies wollen wir an einem Beispiel verdeutlichen, das nebenbei noch eine im ST-Pascal nicht implementierte Funktion liefert - eine Zufallszahl.
Zuerst einmal muĂ die Funktion deklariert werden, dies geschieht durch:
function RANDOM : Integer ; GEMDOS (5)
Der Aufruf erfolgt dann einfach durch:
writeln( RANDOM )
Listing 1 zeigt das dazugehörige Programm:
program RANDOM;
var ch : char;
function RANDOM_INT ; integer; xbios(17);
function RANDOM_LONG : long_integer; xbios(17);
function RANDOM__REAL : real; xbios (17} ;
function RANDOM_CHAR : char; xbios(17);
function RANDOM_BOOL : boolean; xbios(17);
begin
repeat
writefehr(27),'E');
writeln(RANDOM_INT);
writeln(RANDOM_LONG);
writeln(RANDOM_REAL);
writeIn(RANDOM_CHAR);
writeln(RANDOM_BOOL);
read(ch);
until Ch<>' ';
end .
Listing 1
Das System gibt eine 24-Bit Zufallszahl zurĂŒck; je nach gewĂ€hltem Datentyp der Deklaration kann man aber trotzdem jeden Datentyp zurĂŒckerhalten.
Die ParameterĂŒbergabe erfolgt wie in normalen Pascal-Funktionen/Prozeduren. Der Befehl 'GEMDOS (x)â sorgt fĂŒr den Aufruf des GEMDOS Befehls. Entsprechend ist die Deklaration der XBIOS und BIOS Routinen.
Anmerkung: Die Beispiele wurden vorwiegend mit CCD-Pascal von Atari erstellt. Eine Ăbertragung auf andere Compiler ist aber kein Problem, falls Betriebssystemaufrufe dort möglich sind.
Der Bildschirm
- Bildschirmadresse
- Auflösung
- mehrere Grafikseiten
Wie die Ăberschrift schon vermuten lĂ€Ăt, dreht es sich im nĂ€chsten Abschnitt um Befehle, die auf den Bildschirm zugreifen. Man kann sie als ErgĂ€nzung zu den normalenâ Grafikbefehlen sehen.
Beispiel: Sie haben ein Diagramm erstellt und wollen es zur spÀteren Ansicht auf Diskette sichern. Dazu benötigt man zuerst die Anfangsadresse der Grafikseite. Nun, diese liegt nicht bei jedem Rechner gleich (siehe Tabelle 1).
Rechner Anfangsadresse d. Bildschirms
1 Mega 1015808
512 k 491519
ROMs wie der entspr. Rechner
Tabelle 1
Zwar kann man die Adresse fĂŒr seinen Rechner in Erfahrung bringen und diese direkt angeben; es ist aber eine unschöne Art, den ST zu programmieren, das nebenbei noch zu InkompatibilitĂ€t der Software fĂŒhrt. Beweise dafĂŒr gibt es auch im Bereich der 'professionellen' Software. Sogar dort kam es vor, daĂ ein Programm mit einer neuerschienenen TOS-Version - das ist nun endlich vorĂŒber - nicht mehr lief. Der Grund dafĂŒr war meistens der direkte Zugriff auf Speicherstellen, die in der neueren Version an einer anderen Stelle lagen. Um dies zu vermeiden, sollte man die entsprechenden Routinen benutzen, die dann automatisch die jeweils passenden Werte liefern. Am Beispiel der Bildschirmadresse sieht man, daĂ dies ganz einfach ist. Die Routine LOGBASE liefert die Adresse, bei der der Bildschirm beginnt (siehe Listing 2).
Mit dem daraus gewonnenen Wert kann man die Routinen zum Bildschirmspeichern bzw. -lesen ansprechen.
Doch zuerst noch ein paar Worte zu den Grafikseiten im ST. Es ist möglich, mehr als nur die eine sichtbare Grafikseite im Rechner anzulegen und zu verwalten. Mit einem Systemaufruf (SETSCREEN) lĂ€Ăt sich dann jede Seite anwĂ€hlen bzw. zur sichtbaren erklĂ€ren.
Der ST muĂ dabei zwischen der sichtbaren Seite und den anderen unterscheiden können. DafĂŒr gibt es die Funktion PHYSBASE (Listing 3).
Sie zeigt auf den Speicherbereich, der momentan auf dem Bildschirm abgebildet wird. Der Wert dieser Funktion ist also normalerweise mit dem der Funktion LOGBASE identisch, denn es wird meistens auf der Bildschirmseite gearbeitet, die auch angezeigt wird. LOGBASE muĂ aber nicht zwangsweise auf die sichtbare Bildschirmseite zeigen, sondern auch auf eine beliebige andere ist möglich. Auf dieser Seite werden dann alle Bildschirmanweisungen (z. B. Text- und Grafikbefehle) ausgefĂŒhrt. Der Systemaufruf SETSCREEN ermöglicht es, nun eine bestimmte Bildschirmseite anzuzeigen und auf einer anderen zu zeichnen, oder aber zwischen verschiedenen Seiten umzuschalten (siehe z. B. DEGAS). Im Beispiel (Listing 4) werden zwei zusĂ€tzliche Grafikseiten erzeugt und nacheinander aktiviert.
SETSCREEN verlangt als Parameter die Speicheradresse des logischen und physikalischen Bildschirms.
program Bildschirm_logisch;
function LOGBASE : long_integer; xbios(3);
begin
writeln(LOGBASE );
readln
end.
Listing 2
program Bildschirm_physikalisch;
function PHYSBASE : long_integer; xbios(2);
begin
writeln(PHYSBASE );
readln
end.
Listing 3
($S5) ( Lebensnotwendig )
program setscreen:
var bild1,bild2,lognorm.physnorm : long_i nteger ;
a : integer;
procedure setscreen (logisch,phys: long_integer;rest: integer); xbios(5):
function logbase: long__integer; xbios(3);
function physbase : long_integer; xbios(2);
function malloc (wieviel:long_integer) :long_integer ; gemdos ($46);
begin
lognorm :=logbase: { Normalwerte sichern }
physnorm := physbase; { " }
if malloc (-1) > 2*32255 then begin {Platz fuer 2 Bilder ? }
bild1:-ma11oc(32255)+255; { Speicher reservieren }
bild1:=bild1 - (bild1 mod 256); { auf 256'er vAdresse setzen }
bild2;-mal loc(32255)+255: { " }
bild2:-bild2 - (bild2 mod 256): { " }
writeln (chr(27),âE Dies ist der normale Bildschirmâ);
for a:=0 to 10 do writeln ('Halloâ);
writeln (' bitte RETURN druecken');
setscreen (bild1. bild1,-1) { Ausgabe auf Bild 1 lenken }
writeln (chr(27),'E Dies ist der zweite Bildschirmâ);
for a:=0 to 639 do put_pixel (a,200-round(50*sin(a/20)), 1) ;
setscreen (bild2, bild2,-1): { Ausgabe auf Bild 2 lenken }
writeln (chr(27),âE Dies ist der dritte Bildschirm');
for a:=0 to 639 do
line(a,200,a,trunc(sin(a/20)* 100+200),1,1,1,1,$ffff,0) :
for a:=0 to 5 do begin
setscreen (-1.physnorm.-1);{ Normalbild zeigen }
readln ;
setscreen (-1, bild1,-1); { Bild 1 zeigen }
readln :
setscreen (-1. bild2,-1); { Bild 2 zeigen }
readln:
end
end
else begin
writeln (' Zu wenig Speicher fuer zwei neue Bildschirme ');
readln;
end;
setscreen (lognorm, physnorm, -1) ; { Normalzustand herstellen }
{ sonst sehr uebel }
end .
Listing 4
program Grafikaufloesung:
var res : byte;
function GETREZ: integer; xbios(4);
begin
write('SIE arbeiten in der ')
case GETREZ of
0 : writelnt('niedrigen (sehr bunten) Aufloesung');
1 ; writeIn(' mittleren (bunten) Aufloesungâ);
2 ; writeln(âhohen (monochromen) Aufloesung ');
end;
readln
end.
Listing 5
{$S1} { reserviert etwas Speicher }
Program MALLOC;
function MALLOC (groesse:long_integer): long_integer; gemdos ($48);
var groesse, adresse: long_integer;
begin
groesse:= 1000;
adresse:= MALLOC( Groesse ):
writeln ( SIE haben einen '.groesse.' Byte grossen Bereich ab Adresse ', adresse,' reserviert')
end.
Listing 6
{$S1} { reserviert 1K Speicher }
program MALLOC;
function MALLOC(groesse: long_ integer) : long__integer; gerndos ( $48) ;
begin
writeln('SIE haben noch '.MALLOC(-1),' Byte freien Speicher !');
end.
Listing 7
Bei SETSCREEN taucht noch ein weiterer Parameter auf - die momentane Bildschirmauflösung. Diese ist beim Farbmonitor 0 oder 1, beim Monochrommonitor 2. Erfragt werden kann die Auflösung mit der Funktion GETREZ (get resolution). Ein einfaches Beispiel dafĂŒr ist Listing 5 zu entnehmen.
Wenn man bei der Prozedur SETSCREEN einen Parameter nicht Ă€ndern will, so schreibt man anstelle des Wertes eine â â1â in den Prozeduraufruf, z. B. Anzeigen einer anderen Bildseite:
setscreen (-1,neues__bild,-1)
Der logische Bildschirm und die Auflösung werden nicht verĂ€ndert. Nebenbei kann man durch Umschalten der Auflösung, z. B. von FĂ€rb- auf Monochrombetrieb den Rechner schön âin die WĂŒste schickenâ.
Das Beispielprogramm SCREEN (Listing 6) zeigt die prinzipielle Nutzung aller Prozeduren bzw. Funktionen, je nach Anwendung kann man spezielle Prozeduren gestalten, beispielsweise âSWITCH____SCREENâ oder âSHOW_SCREENâ. Als weitere Anregung sei das Umschalten der Bildschirme mit der Maus genannt, doch dazu spĂ€ter.
Wichtig: bevor man das eigene Programm verlĂ€Ăt, sollte man unbedingt die logische und physikalische Adresse wieder angleichen, da sonst der Effekt einem Absturz nahe kommt (Wo ist bloĂ die Maus??).
Um Speicherplatz fĂŒr andere Grafikseiten zu reservieren, ruft man die Systemroutine MALLOC auf. Dazu wird der Funktion die GröĂe des Speichers in Byte ĂŒbergeben (Listing 7).
Die Funktion liefert dann die Anfangsadresse des reservierten Bereiches. Bei Verwendung als zusÀtzliche Bildschirmseite, sollte beachtet werden, daà der Videochip nur Adressen in 256-Byte-Schritten akzeptiert, andernfalls erscheint das Bild verschoben.
Wie aus dem Programm SCREENS ersichtlich, kann mit einer kleinen VerknĂŒpfung die Anfangsadresse auf eine dem Videochip genehme Adresse (n-*256) gelegt werden. Dazu wird ein kleiner Puffer belegt, der die Verschiebung auffĂ€ngt (max. 255 Bytes).
Anmerkung: Da die Funktion MALLOC keinen Speicher bereitstellt, wenn die gewĂŒnschte GröĂe nicht mehr verfĂŒgbar ist, sollte der Benutzer diesen möglichen Fehler entsprechend abfan-gen. Dies ist z. B. durch einen Aufruf der Routine mit dem Wert -1 möglich, denn dann wird der noch freie Speicherplatz (in Byte) zurĂŒckgegeben.
Doch nun zum ersten Programm, das die bis jetzt vorgestellten Prozedur- und Funktionsaufrufe verwendet. Das Programm SCREENS schreibt auf drei verschiedene Bildschirme und schaltet anschlieĂend zwischen ihnen hin und her.
Da in dem Programm die Funktion MALLOC aufgerufen wird, wird erst einmal 5k Speicher reserviert ([$S5J). Danach werden die Adressen des logischen und physikalischen Speichers gesichert, weil sie vor Verlassen des Programms wieder auf diese Werte eingestellt werden mĂŒssen. Ansonsten ist es möglich, daĂ auf eine andere Seite geschrieben wird als auf die angezeigte.
Der nĂ€chste Schritt dient der ĂberprĂŒfung, ob genĂŒgend Speicherplatz vorhanden ist, um zwei weitere Bildschirmseiten zu verwalten. Ist dies nicht der Fall, wird das Programm abgebrochen.
Als nÀchstes werden die Anfangsadressen der neuen Bildschirmseiten ermittelt. Sie werden in den Long__Integer Variablen bildl und bild2 abgelegt.
Das Programm schreibt nun auf den 'normalenâ Bildschirm, schaltet auf den zweiten um, beschreibt diesen usw. Danach kann durch DrĂŒcken von < Return > zwischen den Seiten umgeschaltet werden.
Beim Experimentieren mit mehreren Bildschirmen findet man schnell heraus, daĂ bei Ăberschreiben des Bildschirmrandes auf die benachbarte Grafikseite gezeichnet wird. Deshalb ist es ratsam, den Ausgabebereich mit der Funktion set___clipping zu begrenzen, falls nĂ€mlich keine zweite Grafikseite angrenzt, kann eine solche Ăberschreitung des Bildschirmes leicht zum Erzeugen der bei allen ST-Besitzern so beliebten Bomben fĂŒhren.
Vermieden wird dies durch folgenden, im ST-Pascal vorhandenen, Aufruf:
Set__clipping (true,xmin,ymin,xmax,ymax)
Ein Absichern des gesamten Bildschirmbereiches geschieht folglich durch:
Set__clipping (1,0,0,639,399)
Soviel fĂŒr dieses Mal - leider reicht der Platz nicht mehr. In den nĂ€chsten Teilen wird das Laden und Speichern von Grafikbildern besprochen, sowie einige Befehle zu den Themen FLOPPY, Sound und neue Farbroutinen.
Falls Ihnen etwas zu den vorgestellten oder angekĂŒndigten Themen oder zu anderen Pascal-Tricks einfĂ€llt, so lassen Sie es uns hören.
Wir wĂŒrden uns ĂŒber Ihre Beteiligung sehr freuen.
(MN & HS)