Schönere Programme durch Zeichensätze: Fonts unter ST-pascal plus

GEM bietet einige sehr interessante Möglichkeiten, die auf dem ST leider noch gar nicht richtig ausgenutzt werden. Ein wichtiger Punkt dabei sind die Textdarstellungen. Da jeder Text im Grafikmodus ausgegeben wird, bietet GEM (VDI) die Möglichkeit, verschiedene Textattribute (fett usw.) einzustellen und die Textgröße zu wählen. Davon machen ja auch schon viele Programme (v.a. im Grafikbereich) reichlich Gebrauch. Die Entwickler von GEM sind aber noch einen sehr großen Schritt weitergegangen.

Man kann außer den Systemzeichensätzen noch andere Fonts von Diskette laden (sollte man wenigstens können). Das Format dabei ist außerdem recht flexibel (Proportionalschrift usw.). Dabei tritt nur ein großes Problem auf: die Implementation auf dem Atari ST. Diese ist nämlich nicht ganz vollständig, bzw. fehlerfrei. Mit dem normalen, nicht erweiterten Betriebssystem ist es deshalb nicht möglich, diese Zeichensätze zu benutzen.

Aus diesem Grund gibt es prinzipiell zwei Möglichkeiten, auf dem ST-Zeichensätze zu laden.

Die eine ist sozusagen die offizielle: Man packt das Programm GDOS.PRG (gehört nicht zum Lieferumfang des ST) in den Autoordner der Programm-bzw. Systemdiskette, muß alle einzelnen Fontgrößen auf diese Diskette kopieren und die möglichen Fonts vorher in einer Datei namens ASSIGN.SYS festlegen. Dann, und nur dann, kann das eigentliche Programm die VDI-Funktionen vst_load_fonts und vst_unload_fonts (119 und 120) benutzen, da sie dann funktionieren. Dieses Verfahren kann man natürlich anwenden, es hat aber im Vergleich zu dem folgenden sehr viele Nachteile: der Anwender muß neu booten (wer bootet schon immer mit GDOS.PRG und dem richtigen ASSIGN.SYS), die Zeichensätze sind vorher festgelegt (es kann nicht im Programm gewählt werden), und es schwirren sehr viele Dateien im Hauptdirectory (zwingend!) der Diskette rum, für jede Größe eine.

Deshalb sollte sich bei Interesse auf jeden Fall mi folgendem Verfahren näher beschäftigen: Die Zeichensatzdateien werden direkt in den Speicher geladen. Sie haben ja einen definierten Aufbau und auch die interne Organisation der Fonts ist dokumentiert. Dies ist gar nicht so schwierig, wie es zunächst erscheinen mag, allerdings auch nicht ganz einfach.

Im folgenden beschreibe ich eine Lösung für GEM-Programme unter ST-Pascal plus. Die Anwendung ist recht einfach, da es sich lediglich um zwei Include-Dateien handelt, die einige Funktionen zur Zeichensatzanwendung zur Verfügung stellen. Um das Prinzip zu verstehen, sollte man sich den Aufbau von Font-Dateien verdeutlichen. Jeder Zeichensatz besteht prinzipiell aus zwei Teilen, dem Font-Header und den eigentlichen Zeichensatzdaten und einer (oder zwei) Tabellen. Für die Lösung unseres Problems ist vor allem der Font-Header interessant. Für Pascal läßt er sich als Record darstellen, wie es in FONTTYPE.PAS (Listing 1) geschehen ist. Sehr wichtig ist der Eintrag NextFont, da alle geladenen Fonts im Speicher über diesen Zeiger verkettet sind. Die anderen Einträge sind auch wichtig, allerdings verweise ich für genauere Informationen auf die unten angegebenen Publikationen, vor allem auf das zweite Sonderheft der ST-Computer. Außerdem sollten Sie sich einmal das Listing 1 ansehen, da ich im folgenden von Datentypen spreche, die dort definiert sind.

Das Prinzip beim Laden eines Fonts besteht darin, vom Betriebssystem entsprechend Speicher anzufordern, die Datei dorthin zu laden, und die Zeiger entsprechend zu korrigieren (wie es so schön heißt, den Zeichensatz in die Liste einzuhängen). Ganz so einfach ist es allerdings nicht, wie ich weiter unten zeigen werden. Doch wo, werden sich findige Leser jetzt fragen, soll ich den ersten Zeichensatz denn "einhängen'"? Dazu muß man das eigentliche GEM verlassen und die Line-A-Routinen betrachten, die für die Ausgabe von Grafik (und auch Text) auf den Bildschirm zuständig sind. Die Funktion Line-A-Init ($AOOO) gibt drei Adressen zurück, wovon eine auf eine Tabelle zeigt, die wiederum die Adressen der Systemfont-Header enthält (Kommen Sie noch mit?). Aus dieser Tatsache ergibt sich auch die Aufgabe einer Prozedur in meinen Routinen, nämlich von FirstFontPtr. Diese Funktion liefert einen Zeiger auf den Header des ersten GEM-Fonts zurück (Datentyp FontPtr, oder auch Font).

Wie oben schon erwähnt, ist dazu allerdings etwas Assembler notwendig. Der Einfachheit halber habe ich diese kurze Routine in ein Feld gepackt und zum Aufruf die XBios-Routine SupExec (38) benutzt. Der Aufruf erfolgt zwar im Supervisormodus, und man darf keine Betriebssystemfunktionen benutzen, aber das stört hier nicht (dieses Verfahren bietet sich sowieso bei kleinen Routinen an, wenn man nicht gleich eine extra Objekt-Datei nutzen will.) Nach Aufruf dieser Funktion steht in Routine. Pointer die Adresse des ersten GEM-Fonts (gleich als richtiger Typ). Für Interessierte: Der Quelltext der Routine steht in FONT1NIT.ASM (Listing 2b). LastFontPtr benutzt FirstFontPtr und “hangelt" sich dann die Liste entlang, um den letzen Font zu bestimmen. Dort werden neue Fonts angehängt.

Um einen Zeichensatz zu laden (FNT-Datei), wird die Funktion LoadFont benutzt. Diese öffnet die Datei und ruft dann InstallFont auf. InstallFont erledigt die eigentliche Arbeit. Ich möchte das eigentliche Funktionsprinzip nur kurz beschreiben, sehen Sie sich das Listing an, oder benutzen Sie die angegebene Literatur.

Zuerst wird entsprechend der Dateilänge vom Betriebssystem Speicher angefordert. Aus diesem Grund muß bei Benutzung von FONTSUBS folgendes auf jedem Fall gewährleistet sein: Das Betriebssystem muß genügend Speicher haben! Also am besten die U-Option des Compilers benutzen: {$U 100} wird wohl reichen. Nachdem also hoffentlich Speicher reserviert werden konnte, wird die Datei an diese Stelle mit Hilfe von FRead (Gemdos) eingelesen. Nun folgen aber noch einige Operationen, die vor allem folgenden Sinn haben: Da GEM auch auf PCs zu finden ist. sind im Fontheader und in den Tabellen Worte im Intel-Format abgespeichert (erst Low-Byte, dann Hi-Byte). Im Speicher müssen sie aber richtig vorliegen (der ST benutzt einen MC68000). Aus diesem Grund werden im größten Teil des Fontheaders und in den dann folgenden Tabellen die Worte “motorolatisiert". Die eigentlichen Zeichensatzdaten sind aber schon richtig vorhanden (wenn auf dem ST erstellt). Nach diesen Vorgängen werden die Offsets noch zu Adressen erweitert und der Zeichensatz in die Liste "eingehängt". InstallFont gibt dann den Zeiger auf den Zeichensatz als FontPtr zurück. Die entgegengesetzte Funktion zu LoadFont ist UnloadFont. Der Zeichensatz wird aus der Liste "ausgehängt" und der belegte Speicher wieder freigegeben.

Mit diesen beiden Funktionen können Sie schon mehr machen als mit den Original-Funktionen. Wenn Sie einen Zeichensatz laden wollen, müssen Sie folgendermaßen vorgehen: Sie fügen in GEM-Programmen (und nur dort) hinter {SIGEMTYPE) bzw. {SIGEMSUBS) {$IFONTTYPE} und {$IFONTSUBS} ein und deklarieren dann eine Variable vom Typ Font. Um dann einen Zeichensatz zu laden, machen Sie folgendes (Ihre Variable heißt z.B. Zeichens):

Zeidiens:=LoadFont('DATEINAM.FNT',2);

'DATEI NAM.FNT' steht dabei für den Namen der Fontdatei, die 2 für die Nummer, unter der der Font angesprochen werden soll. Wenn Zeichens danach NIL ist, ist ein Fehler aufgetreten (Datei nicht vorhanden, zu wenig Speicher).

Wenn Sie nun diese Schrift benötigen, kommt Text_Face zum Einsatz: Text_Face(2); wählt den Font mit der Nummer zwei. Alle Grafik-Text-Ausgaben benutzen dann diesen Font bis Sie mit Text_Face( 1); wieder den Systemfont einschalten. So einfach kann die Anwendung von Zeichensätzen sein (oder ist das etwa nicht einfach ?!). Vor Programmende müssen Sie dann nur noch Unload Font(Zeichens); aufrufen, um den Speicher wieder ordnungsgemäß freizugeben.

Bis hierhin ist es ja schon ganz schön und ich war auch ganz erfreut, daß ich nach einigen Mühen und leider auch Abstürzen zum ersten Mal Proportionalschrift auf dem “Pascal-Bildschirm” sah. Es bleibt nur noch ein Problem: die vielen Dateien auf den Disketten. Eine eigene Datei für jede Größe jedes Zeichensatzes ist nun wirklich nicht nötig. Es sieht nicht nur unübersichtlich aus, sondern benötigt effektiv auch mehr Platz auf der Diskette und mehr Ladezeit. Deshalb habe ich mir ein Format ausgedacht, um mehrere Dateien sinnvoll zusammenzufassen. Es ist zugegebenermaßen nicht sehr aufwendig, aber dafür extrem nützlich. Hier nun eine Beschreibung dieses Formats:

Die ersten zwölf Bytes stellen eine Kennung da, um die Datei zu identifizieren. Sie müssen “ZSA-GEM-FONT” enthalten, da ich solch eine Datei ZSA-Datei nenne (von Zeichensatz, klar?).

Das nächste Wort gibt nun die Anzahl der verschiedenen Fontarten (Faces) an. Für jedes Face wiederholen sich die folgenden Daten:

1 Wort: Anzahl der Zeichensatzgrößen für jedes Face.

Für diese einzelnen Größen wiederholen sich nun wiederum die nächsten Daten:

1 Wort: Länge der eigentlichen Zeichensatzdatei (FNT).

danach: Die Daten dieser FNT-Datei ohne jede Änderung.

Wenn man eine so aufgebaute Datei laden will, kommen andere Funktionen zum Einsatz. Sie brauchen keine Variable des Types Font mehr, sondern dafür eine vom Typ FontList. Der Funktion LoadZsaFonts übergeben Sie folgende Parameter:

Zuerst wieder den Dateinamen (*.ZSA), dann die Face-Nummer; diese Face-Nummer gilt für den ersten geladenen Face. Alle weiteren Faces werden fortlaufend numeriert. Der letze Parameter ist die eben erwähnte “Font-Liste”. Die Funktion LoadZsaFonts lädt alle Fonts in den Speicher. Das genaue Vorgehen entnehmen Sie bitte dem Listing. Es wird auch InstallFont benutzt, die Hauptsache funktioniert also genauso wie bei LoadFont. LoadZsaFonts gibt die Anzahl der korrekt geladenden Faces zurück. Bei Auftreten eines Fehlers ist der Funktionswert Null.

Die nachgeladenen Fonts können Sie dann mit Text_Face(2,3,4 usw.) ansprechen. Wenn das Programm mit seiner Arbeit fertig ist, muß es nicht UnloadFont sondern UnloadFonts (das kleine s ist wichtig!) aufrufen. UnloadFonts verlangt genau wie UnloadFont einen Parameter, aber nicht vom Typ Font, sondern vom Typ FontList. Es werden alle Zeichensätze freigegeben, und es kann auf sie nicht mehr zugegriffen werden.

Mehrere Zeichensätze in einer Datei

Meiner Meinung nach sind diese zusammengefaßten Zeichensätze in den meisten Fällen eine große Erleichterung. Um nun auch das Erstellen einer solchen Datei zu erleichtern, habe ich ein kleines GFA-Basic-Programm geschrieben (Listing 4). Es ist zwar nicht sehr komfortabel, aber trotzdem ist die Bedienung recht einfach, so daß ich hier nicht weiter darauf eingehe.

Das Anwenden von GEM-Fonts reduziert sich durch diese Routine auf folgende Schritte: Include-Files an den richtigen Stellen definieren. LoadFont oder LoadZsaFonts mit den entsprechenden Variablen aufrufen. Bei Bedarf mit Text_Face die gewünschte Schriftart bestimmen und am Ende UnloadFont oder UnloadFonts aufrufen.

Einen Hinweis muß ich allerdings noch anbringen: In dieser Form laufen die Routinen nur mit der neuesten Version von Pascal plus. Ich benutze z.B. manchmal Long_Integers als Schleifenvariablen, und außerdem sind in älteren Versionen einige GEM-Funktionen nicht vordefiniert. Ein Umschreiben müßte möglich sein, doch empfehle ich sowieso auf jeden Fall, sich die neueste Version zu besorgen (Das Update ist gar nicht so teuer, es lohnt sich.).

Ab jetzt steht also der Verschönerung von GEM-Programmen durch verschiedene Zeichensätze nichts mehr im Wege. (Außer daß Sie keine Zeichensätze haben?! Da kann ich Ihnen auch nicht helfen. Aber trösten Sie sich, ich habe da auch meine Probleme. Man bekommt wirklich fast keine. Aber vielleicht ändert sich das jetzt; als Anregung: Wer schreibt einen guten Font-Editor?)

Konvertierung der Zeichensätze

Es gibt allerdings eine Lösung für dieses Problem der fehlenden GEM-Zeichensätze: Die Konvertierung von anderen Formaten. Sicherlich gibt es einige Leser, die STAD- oder Font-loader-Fonts haben. Solche gibt es teilweise auch schon auf Public-Domain-Disketten. Nun habe ich ein kleines GFA-Basic-Programm geschrieben, das diese Konvertierung vomimmt. Ein Nachteil ist, daß solche Zeichensätze nicht proportional und nur in der Standardgröße vorhanden sind. Trotzdem lohnt es sich, sie zu benutzen. Es ist immerhin etwas. Zur Anwendung des Programms (Listing 4) ist folgendes zu sagen:

In einer Alert-Box wählen Sie die Art des zu konvertierenden Fonts, dann den Namen. Danach wird er in den Speicher geladen und Sie werden aufgefordert, den Namen einzugeben, der in den Font-Header eingetragen wird. Danach geben Sie den Dateinamen des GEM-Fonts ein und er wird auf Diskette geschrieben. Dazu noch eine Anmerkung: Lassen Sie sich ein System einfallen, um GEM-Fonts von anderen Fonts zu unterscheiden, da alle die Extension “FNT” haben.

Nun noch einige Hinweise zu dem beigefügten Beispielprogramm (Listing 3): Es macht nicht besonders viel: Sie können eine FNT- oder ZSA-Datei wählen und dann Face, Attribute und Größe einstellen. Nach diesen Parametern wird dann ein kleiner Text ausgegeben. Vertiefen Sie sich in das Listing, da das Programm st keinen praktischen Wert hat.

Noch viel Spaß beim Programmieren, vorallem mit dem ausgezeichneten Pascal plus, und vielleicht erstellt ja jemand mal Zeichensätze. Ich würde mich darüber freuen.

Weitere Informationen finden Sie in:

  1. GFA-Basic-Buch (GFA) vor allem im Kapitel Fonts (dort ist eine ähnliche Lösung für GFA-Basic beschrieben).

  2. Atari ST - GEM (Data Becker)

  3. Atari ST Intern (Data Becker)

  4. ST-Computer-Sonderheft 2 (Heim-Verlag)

außerdem natürlich auch noch in anderen Büchern über GEM.

{ Listing 1: }
{ ========== }

{ FONTTYPE.PAS - Typendefinitionen für FONTSUBS.PAS 
				GEM-Fonts unter ST-Pascal plus 
				laden. LPSoft	1987 }

			FontPtr		=	^FontHeader;
			FontHeader	= Record
				FontId	:	Integer;
				FontSize	: Integer;
				FaceName	:	Packed Array [1..32] of Char;
				LowADE	:	Integer;
				HighADE	:	Integer;
				TopLine	:	Integer;
				AscentLine	:	Integer;
				HalfLine	:	Integer;
				DescentLine	:	Integer;
				ButtomLine	:	Integer;
				CharWidth	; Integer;
				CellWidth	:	Integer;
				LeftOffset	:	Integer;
				RightOffset	:	Integer;
				Thickening	:	Integer;
				UnderLineSize	:	Integer;
				LightMask	:	Integer;
				SkewMask	:	Integer;
				Flags	:	Integer;
				HorOffsetTable :	Long__Integer;
				CharOffsetTable :	Long_Integer;
				FontData	:	Long_Integer;
				FormWidth	:	Integer;
				FormHeight	:	Integer;
				NextFont	:	FontPtr;
			End;
			Font	=	FontPtr;
			FontListPtr = ^FontListEle;
			FontListEle = Record
				Pointer	:	FontPtr;
				Next	:	FontListPtr;
			End;
			FontList = FontListPtr;

	{ END OF FONTTYPE.PAS }
{ Listing 2: }
{ ========== }

{ FONTSUBS.PAS - 'GEM-Fonts' unter ST-Pascal plus 
	laden und benutzen. 1987 by LPSoft Lutz Preßler,
	2904 Hatten 23.11.87 }

{ ************* VORHANDENE FUNKTIONEN **************** 
Function LoadFont(<Name:String>,<FaceNo:Integer>): <FontPtr>;
-> Eine Zeichensatzdatei laden (<Name>:*.FNT) und als Face <FaceNo> 
installieren. Rückgabewert (FontPtr): Zeiger auf 
Zeichensatz oder NIL bei Fehler.

Function LoadZsaFonts(<Name:String>,<FaceNo:Integer>, <List:FontList>) : <Integer>
—> Mehrere Zeichensätze im ZSA-Format laden und die darin enthalten Faces ab Nummer <FaceNo> 
	installieren. <Name>:*.ZSA, <List>: Liste von 
	Font-Pointern (für späteren Zugriff und Löschen; muß nicht leer sein).
	Rückgabewert (Integer): Anzahl der geladenen Faces oder 0 bei Fehler.
Procedure UnloadFont(<Ptr:FontPtr>)
-> Einen Zeichensatz (Ptr) löschen. Er kann danach
	nicht mehr benutzt werden, der belegte Speicher wird freigegeben.
Procedure UnloadFonts(<List:FontList>)
—> Mehrere Zeichensätze löschen (Liste der Zeichens.:
	List). Siehe UnloadFont. Die Liste ist danach leer (NIL).
Procedure Text_Face(<FaceNo:Integer>)
—> Textface auswählen. Bei nicht vorhandenem Face wird der Systemfont benutzt.
Die anderen Funktionen werden eigentlich nur intern benötigt.
Anm. : Der Datentyp Font entspricht FontPtr.

************************************************ }

Function FontAdress(Ptr:FontPtr):	Long_Integer;
Var X: Record Case Integer Of
		0:	(Adr: Long_Integer); 
		1:	(Ptr:	FontPtr); 
	End;
Begin {$P~} X.Ptr:=Ptr; FontAdress:=X.Adr; {$P=} End (of FontAdress);
Function FontPointer(Adr:Long_Integer):	FontPtr;
Var X: Record Case Integer Of
		0:	(Adr: Long_Integer); 
		1:	(Ptr:	FontPtr); 
		End;
Begin {$P-} X.Adr:=Adr; FontPointer:=X.Ptr;{$P=} End {of FontPointer};
Function FirstFontPtr: FontPtr;
	Type RoutType = Record
		Code:	Array[1..7]	of	Long_Integer;
		Pointer: FontPtr;
	End;
	Var Routine: RoutType;

	Procedure CallSup(Var Code:RoutType); XBios(38); 
Begin
	Routine.Code[1]:=$48E780E0;
	Routine.Code[2]:=$A0002269;
	Routine.Code[3]:=$00042269;
	Routine.Code[4]:=$005441FA;
	Routine.Code[5]:=$000C2089;
	Routine.Code[6]:=$4CDF0701;
	Routine.Code[7]:=$4E754E71;
	CallSup(Routine);
	FirstFontPtr:=Routine.Pointer;
End {of FirstFontPtr};
Function LastFontPtr: FontPtr;
	Var P: FontPtr;
Begin
	{$P-} P :=FirstFontPtr;
		While P^.NextFont<>NIL do P :=P^.NextFont; 
	LastFontPtr:=P; {$P=}
End {of LastFontPtr};
Function InstallFont(FaceNo,FHandle:Integer;Flang;Long_Integer): FontPtr;
	Var Adr,Anz,I : Long_Integer;
	Ptr,PrPtr : FontPtr;

Function SwapWord(X:Integer):	Integer;
Begin SwapWord:=Shl((X&$FF),8)+(Shr(X,8)&$FF); End; 
Function Malloc(Amount:Long_Integer): Long_Integer;Gemdos($48);
Procedure Fread(H:Integer; C,Buf:Long_Integer);Gemdos($3F);
Function PeekWord(Adr:Long_Integer): Integer;
Var X: Record Case Integer Of
	0:	(Adr: Long_Integer); 
	1:	(Ptr: ^Integer);
End;
Begin {$P-} X.Adr:=Adr; PeekWord:=X.Ptr^; {$P=} End; 
Procedure PokeWord(Adr:Long_Integer; Wert:Integer); 
Var X: Record Case Integer Of
	0: (Adr: Long_Integer);
	1: (Ptr: ^Integer);
End;
Begin {$P-} X.Adr:=Adr; X.Ptr^:=Wert; {$P=} End; 
Begin
	Adr:=Malloc(Flang);
	If Adr<=0 then InstallFont:=NIL else begin 
	Fread(FHandle,Flang,Adr);
	Ptr:=FontPointer(Adr);
	{$P-}
	Anz:=SwapWord(Int(Shr(Ptr^.FontData,16)));
	Ptr^.FontId:=SwapWord(Ptr^.FontId);
	Ptr^.FontSize:=SwapWord(Ptr^.FontSize);
	For I:=18 to (Anz-1) div 2 do
		PokeWord(Adr+I*2,SwapWord(PeekWord(Adr+I*2))); 
		Ptr^.HorOffsetTable:=Adr+Int(Shr(Ptr^.HorOffsetTable,16));
		Ptr^.CharOffsetTable:=Adr+Int(Shr (Ptr^.CharOffsetTable,16));
		Ptr^.FontData:=Adr+Int(Shr(Ptr^.FontData,16)); 
		PrPtr:=LastFontPtr; PrPtr^.NextFont:=Ptr; 
		InstallFont:=Ptr; Ptr^.FontId:=FaceNo;
			Ptr^.NextFont:=NIL;
		{$P=}
	End;
End {of InstallFont};
 Function LoadFont(Name:String;FaceNo:Integer): FontPtr;
 Var Dat	:	Text;
	FHandle	:	Integer;
	Flang,I	:	Long_Integer;
	IOStat	:	Boolean;
  Function Fseek(Offs:Long_Integer; H,M:Integer): Long_Integer; Gemdos($42);
  Function IO_State: Boolean; External;
 Begin
    IOStat:=IO_State; IO_Check(False);
   Reset(Dat,Name);
    If IO_Result<>0 then LoadFont:=NIL else begin 
	 FHandle:=Handle(Dat);
      Flang:=Fseek(0,FHandle,2); I:=Fseek(0,FHandle,0);
      LoadFont:=InstallFont(FaceNo,FHandle,Flang);
   End;
    IO_Check(IOStat);
 End {of LoadFont};
  Function LoadZsaFonts(Name:String; FaceNo:Integer;
      Var ListrFontList): Integer;
  Var Dat	:	Text;
      FHandle,I : Integer;
      Lang	:	Long_Integer;
      IOStat,
      Fehler :	Boolean;
      Test	:	String[8];
      TChar	:	Char;
      FaceAnz,Fa,
      GrAnz,Gr :	Integer;
      Ptr	:	FontPtr;
      LPtr	:	FontList;
  Function IO_State: Boolean; External;
  Function Fseek(Offs:Long_Integer; H,M:Integer): Long_Integer; Gemdos($42);
  Function ReadInt: Long_Integer;
   Type IntegerPtr = ^Integer;
   Var I: IntegerPtr;
    Procedure Fread(H:Integer; C:Long_Integer;
         C,Buf:IntegerPtr); Gemdos($3F);
   Begin
     I:=NIL; New(I);
     FRead(FHandle, 2,1);
     ReadInt:=(IA&$FFFF);
     Dispose(I);
   End;
   Begin
      IOStat:=IO_State; IO_Check(False);
      Reset(Dat,Name);
      If IO_Result<>0 then LoadZsaFonts:=0 else begin 
       Test:='';
       For I:=1 to 4 do Read (Dat, TChar);
       For I:=1 to 8 do begin Read (Dat, TChar);Test[I]:=TChar; End;
       Test[0]:=Chr(8);
       If Test=' GEM-FONT' then begin
         FHandle:=Handle(Dat); Lang:=FSeek(12,FHandle,0); 
         FaceAnz:=ReadInt;
         Fehler:=False;
          For Fa:=FaceNo To FaceNo+FaceAnz-1 do begin 
		    GrAnz:=ReadInt;
            For Gr:=l to GrAnz do begin 
			  If not Fehler then begin 
			   Lang:=ReadInt;
                Ptr:=InstallFont(Fa,FHandle,Lang);
               If Ptr=NIL then begin
                 Fehler:=True; FaceAnz:=Fa-PaceNo; end 
			   else begin 
			     New(LPtr);
                 LPtr^.Pointer:=Ptr;
                 LPtr^.Next:=List;
                 List:=LPtr;
               End;
            End;
         End;
       End;
        LoadZsaFonts:=FaceAnz;
      End else LoadZsaFonts:=0;
    End;
     IO_Check(IOStat);
End {of LoadZsaFonts};

Procedure UnloadFont(Ptr:FontPtr);
Var P: FontPtr;
Procedure FMfree(Adr:FontPtr); Gemdos($49);
Begin
  {$P-} P:=FirstFontPtr;
      While P^.NextFont<>Ptr do P:=P^.NextFont;
  P^.NextFont:=Ptr^.NextFont; {$P=}
  FMfree(Ptr);
End {of UnloadFont};
Procedure UnloadFonts(Var List:FontList) ;
Var P: FontList;
Begin
  P:=List;
  While P<>NIL do begin
     UnloadFont(P^.Pointer);
     List:=P;
     P:=P^.Next;
     Dispose(List);
  End;
  List:=NIL;
End {of UnloadFonts};
Procedure Text_Face(FaceNo:Integer);
Var Control : Ctrl_Parms;
    Int_in : Int_In_Parms; Int_out : Int_Out_Parms; 
	Pts_in : Pts_In_Parms; Pts_out : Pts_Out_Parms;
Begin
   Int_in[0]:=FaceNo;
     VDI_Call(21,0,1,0,Control,Int_in,Int_out,Pts_in, Pts_out,False);
End {of Text_Face};

{ END OF FONTSUBS.PAS }
; Listing 2b:
; ===========
;
Start
  movem.l d0/a0-a2,-(a7)	; Register retten
  dc.w $a000	; Line-A-Init
  movea.l 4(a1),a1	; Adresse des ersten
  movea.l 84(a1),a1	; GEM-Fonts bestimmen
  lea Reg(Pc),a0	; dort soll diese Adresse hin...
  move.l a1, (a0)	; also machen wir das
  movem.l (a7)+,d0/a0-a2	; Register restaurieren
  rts	; und zurück zum Pascal...
  nop 
 Reg ds.l 1 
 End
{ Listing 3: }
{ ======== }

{$U100}

Program Font_Test; { 1987 by LPSoft Lutz Preßler 24.11.1987 }

Const {$IGEMCONST}

Type	{$IGEMTYPE}
		{$IFONTTYPE}

Var	Zeichensatz	: Font;
	Pfad,ZeichsName,FaceNa :	String;
	Thoch,Attribute	:	Integer;
	Ok,Zsa	:	Boolean;
	A1,Anzahl,Face,I	:	Integer;
	ZListe	:	FontList;

{$IGEMSUBS}
{$IFONTSUBS}

Procedure Taste; Gemdos(7);

{ Procedure Text_Heigth(Height:Integer); External; bei mir in GEMSUBS.PAS deklariert. }

Procedure DefText(Color,Style,Rotation,Height,
		Face:Integer);
Begin
	If Face>0 then Text_Face(Face);
	If Color>=0 then Text_Color(Color);
	If Style>=0 then Text_Style(Style);
	If Rotation>=0 then Text_Rotation(Rotation);
	If Height>0 then Text_Heigth(Height);
End;

Procedure FaceName(Faceld:Integer;
	Var FaceName:String);
Var Control : Ctrl_Parms;
	Int_in : Int_In_Parms; Int_out : Int_Out_Parms; 
	Pts_in : Pts_In_Parms; Pts_out : Pts_Out_Parms; 
	I	:	Integer;
Begin
	Int_in[0]:=FaceId;
	VDI_Call(130,0,1,0,Control,Int_in,Int_out,Pts_in, Pts_out,False);
	I:=1;
	Repeat
		FaceName[I]:=Chr(Int_out[I]); I:=I+1;
	Until (I=35) or (FaceName[I-1]=Chr(0));
	FaceName[0]:=Chr(I-2);
End;

Procedure TestAusgabe(F:Integer);
Begin
	Write ('Texthöhe(Pixel) :	'); ReadLn(Thoch);
	If IO_Result<>0 then Thoch:=13;
	Write('Textattribute :	'); ReadLn(Attribute);
	If IO_Result<>0 then Attribute:=0;
	DefText(-1,Attribute,-1,Thoch,F);
	Hide_mouse;
	Draw_String(10,200,'Dies ist ein GEM-Zeichensatz-Test. Lutz Pre_ler'); 
	Show_mouse;
	DefText(-1,0,-1,13,1);
End;
Procedure Bildschirm_loeschen;
Begin 
	Hide_mouse; Clear_Screen; 
	Write(Chr(27),' H'); Show_mouse; 
End;

Begin If Init_Gem>=0 then begin 
	Bildschirm_loeschen;
	Set_Clip(0,0,640,400);
	WriteLn ('Letzter Font HEX:	',FontAdress(LastFontPtr):8:h);
	Repeat
		A1:=Do_Alert('[1][LPSoft-Pasca1-GEM-Font-Demo| Welche Zeichensatz-Art?][FNT|ZSA|ENDE]',1); 
		Ok:=(A1<>3);
		If Ok then begin 
			Zsa:=(A1=2);
			If Zsa then Pfad:='\*.ZSA' else Pfad:='\*.FNT' ; 
			ZeichsName:=' ';
			Ok:=Get_In_File(Pfad,ZeichsName);
			If Ok then begin
				Bildschirm_loeschen;
				If Zsa then begin 
					ZListe:=NIL;
					Anzahl:=LoadZsaFonts(ZeichsName,2,ZListe);
					If Anzahl=0 then WriteLn('FEHLER!') else begin WriteLn('Geladene Faces');
					For I:=2 to Anzahl+1 do begin 
						FaceName(I,FaceNa) ;
						WriteLn(I:2,':	',FaceNa);
					End;
					Taste; Bildschirm_loeschen;
					WriteLn('Letzter Font HEX: ',FontAdress(LastFontPtr):8:h);
					Repeat
						IO_Check(False);
						Write('Face (von 1 bis ',Anzahl+1,',Ende=0): '); ReadLn(Face);
						If IO_Result<>0 then Face:=0;
						If Face>0 then begin 
							TestAusgabe(Face);
							IO_Check(True);
							Taste;
						End;
						Bildschirm_loeschen;
					Until Face=0;
					UnloadFonts(ZListe);
					WriteLn ('Letzter Font HEX:	', FontAdress(LastFontPtr):8:h);
				End
			End else begin
				Zeichensatz:=LoadFont(ZeichsName,2);
				If Zeichensatz=NIL then WriteLn('FEHLER!') else begin 
					FaceName(2,FaceNa);
					WriteLn('Face-Name:	',FaceNa);
					WriteLn('Letzter Font HEX:	',FontAdress(LastFontPtr):8:h);
					IO_Check(False);
					TestAusgabe(2);
					IO_Check(True) ;
					UnloadFont(Zeichensatz) ;
					WriteLn('Letzter Font HEX:	',FontAdress(LastFontPtr):8:h);
					Taste;
				End;
			End;
		End;
	End;
Until Ok=False;
Exit_Gem; End; End.
' Listing 4:
'
' Mehrere GEM (*.FNT) - Fonts zu einer Datei (*.ZSA) zusammenfassen.
' 1987 LPSoft, Lutz Preßler

Print " GEM-Fonts zu einer *.ZSA-Datei zusammenfassen." 
Print " ";StringS(46,"-")
Print " Erzeuge Datei ...        ";
Fileselect ”\*.ZSA","",Ausgabef$
Print Ausgabef$
Open "O",#1, Ausgabef$
Print #1, "ZSA-GEM-FONT*;
Input " Wieviele Faces ?         ",Faces%
Print #1,Mki$(Faces%);
For F%=1 Tc Faces%
	Print " Face ";F%;" : Wieviele Größen ? ";
	Input "",Groessen%
	Print #1,Mki$(Groessen%);
	For G%=1 To Groessen%
		Print " Grö_e ";G%;" ...              ",
		Fileselect "\*.FNT",Name$
		Print Name$
		Open "I",#2,Name$
		Laenge%=Lof(#2)
		Print #1,Mki$(Laenge%);
		While Laenge%>32000
			Print #1,Input$(32000,#2);
			Sub Laenge%,32000 
		Wend
		Print #1,Input$(Laenge%, #2);
		Close #2 
	Next G%
Next F%
Close #1 
Print " Ok."
Void Inp(2)
Edit
' Listing 4:
' ==========
'
' *** Font-Konvertierung von STAD- oder Fontloader-Format zu GEM-Font ***
' *** 1987 by LPSoft Lutz Pre_ler, Sandkrug, Ahornweg 11, 2904 Hatten ***
'
Repeat
	Cls
	Alert 1,"Font-Konvertierung , LPSoft|STAD- oder Fontloader-Fonts| in GEM-Fonts umwandeln.",1, "STAD|FONTLOAD|ENDE",Res 
	If Res=3 
		Edit 
	Endif
	Fileselect "\*.FNT","",A$
	If A$="" Or Right$(A$)="\"
		Edit
	Endif
	If Exist(A$)
		Open "I",#1,A$
		Chars%=(Lof(#1)/16*Res)+32*(Res=2)
		If Chars%>256 Or Chars%=0 Or (Res=2 And Chars%<65) 
			Print "Falsches Datei-Format!"
			Void Inp(2)
			Edit
		Endif
		If Res=2 And Chars%>96 
			Chars%=96 
		Endif
		Dat$=Space$(Lof(#1)*Res+256*(Res=2))
		'
		If Res=1
			For I=0 To Chars%-1 
				For B=0 To 15
					Poke Varptr(Dat$)+I+B*Chars%,Inp(#1)
				Next B 
			Next I 
			Lowade%=0 
		Else
			For I=0 To Chars%+31 
				If I>64 And I<=96 
					For B=0 To 7 
						Void Inp(#1)
					Next B 
				Else
					J=I+32*(I>96)
					For B=0 To 7
						Poke Varptr(Dat$)+J+B*2*Chars%, Inp(#1)
						Poke Varptr(Dat$)+J+(B*2+1)*Chars%,Peek(Varptr(Dat$)+J+B*2*Chars%)
					Next B 
				Endif 
			Next I 
			Lowade%=32 
		Endif
		'
		Highade%=Lowade%+Chars%-1 
		If Res=2
			Name$="Fontloader-Font"
		Else
			Name$="STAD-Font"
		Endif
		Print "Fontname: ";
		Form Input 31 As Name$
		Name$=Left$(Name$+String$(32,0),32)
		'
		Head$=Mki$(0)+Mki$(&HA00)+Name$
		Head$=Head$+Chr$(Lowade%)+Chr$(0)
		Head$=Head$+Chr$(Highade%)+Chr$(0)
		Restore Header.data 
		For I=1 To 18 
			Read Za$
			Head$=Head$+Mki$(Val("&H"+Za$))
		Next I
		Head$=Head$+Chr$((88+2*(Chars%+1)) Mod 256)+Chr$((88+2*(Chars%+1))\256)+Mki$(0) 
		Head$=Head$+Chr$(Chars% Mod 256)+Chr$(Chars%\256)+ Mki$(&H1000)+Mkl$(0)
		For I=0 To Chars%
			Head$=Head$+Chr$((I*8) Mod 256)+Chr$((I*8)\256) 
		Next I
		'
		Header.data:
		Data 0D00,0B00,0800,0200,0200,0700,0800,0100,0700, 0100,0100,5555,5555,0800,0000,0000,5800,0000
		'
		Fileselect "\*.FNT","",A$
		If A$<>"" And Right$(A$)<>"\"
			Open "O",#2,A$
			Bput #2,Varptr(Head$),88+2*(Chars%+1)
			Bput #2,Varptr(Dat$),Len(Dat$)
		Endif
		Close
		Print "Ok."
	Endif
	Alert 2,"Noch einen Font umwandeln?",1,"JA|NEIN",Res 
Until Res=2 
Edit
; *** FONTLOADER - STAD-Font als neuen Systemfont ***
; *** (sowohl GEM als auch TOS) installieren. *** 
; *** auch für AUTO-Ordner(ohne Param.=SYSFONT.FNT) *** 
; *** 10.12.1987 by LPSoft,Lutz Pre_ler,2904 Hatten ***
;
; Konstantendefinitionen 
	GemDos equ 1 
	Keep equ $31 
	FOpen equ $3D 
	FClose equ $3E 
	FRead equ $3F 
	FSeek equ $42 
	FSetDTA equ $1A 
	FSFirst equ $4E 
	Bios equ 13 
	Xbios equ 14 
	GetRez equ 4 
	SupExe equ 38
;
; Programmlänge berechnen 
	move.l 4(a7),a0 
	move.1 #Text,d6
	sub.l a0,d6	; d6 = zu reserv. Bereich
;
	adda.l #129,a0
	movea.l a0,a6	; Adresse der Commandline
	clr.l d0	; Null-Byte	ans Ende setzen
	move.b -1(a0),d0 
	clr.b (a0,d0.b)
; Auflösung überprüfen 
	move #GetRez,-(a7) 
	trap #XBios 
	addq.l #2,-(a7) 
	lea WrongRes,a0 
	cmpi #2,d0
	bne Error ; Fehlermeldung
;
	move.l #Ok,Text ; Default-Text nach Installation
;
; Programm schon resident? 
	move.l #GetTrap,-(a7) 
	move #SupExe,-(a7) 
	trap #XBios 
	addq.l #6,a7 
; movea.l OldTrap,a0 
	clr.b d2
	movea.l #FontData,a4 ; Adresse des Fontbereichs 
	cmpi.l #"Lutz",-4(a0) 
	bne.s NichtRes
	move.b #$ff,d2	; Flag für "resident" setzen
	movea.l -12(a0),a4	; jetzt vorhandene Fontadresse
	move.l -8(a0),OldFont	; Adresse des Origina1-Fonts
	move.l -16(a0),GemDosTrap 
	move.l -20(a0),OldTrap 
; Commandline "#" oder "~"
	move.b (a6),d0 
	cmpi.b #"~",d0 
	beq.s RAend 
	move.b (a6),d0 
	cmpi.b #"#",d0 
	bne.s RWeiter 
RAend
	move.l	#Sys,Text	; ja: Ausgabetext ändern
;
	bra.s RWeiter
NichtRes	; Programm noch nicht resident:
	movea.l #Info,a0	; Info anzeigen
	bsr Message
	move.b	(a6),d0	; Commandline
	cmpi.b #"~",d0
	beq.s RFehler	; oder
	move.b (a6),d0
	cmpi.b	#"#",d0	; Commandline "#"
	bne.s RWeiter 
RFehler
	movea.l #Exit,a0	; ja: geht nicht —>	Hinweise
	bsr Message	; zur Anwendung	anzeigen
	bsr Key	; Auf Tastendruck warten
	bra FResi	; Programm normal beenden
RWeiter
	move.b d2,Flag	; "resident"-Flag abspeichern
;
	bsr FontLaden	; —>Fontdatei(4096 Bytes)laden
; Font installieren 
; Font-Adressen bestimmen 
	dc.w $A000 
	movea.1 4(a1),a3 
	movea.1 84(a3),a3 
	move.1 a3,FontBase 
	move.l 76(a3),d0 
	tst.l d0 
	beq FAuto 
	move.1 d0,OldFont
	move.l a4,76(a3)	; Adresse eintragen
FAuto 
	move.l a4,FontAdr 
; Font anmelden (direkt zugreifen) 
	dc.w $A000 
	move.l a4,-22(a0)
; Text ausgeben 
	movea.l Text,a0 
	bsr Message 
; Commandline "~"?
	move.b (a6),d0 
	cmpi.b #"~",d0 
	bne.s TextEnde 
	movea.l #NichtResiT,a0 
	bsr Message 
TextEnde
	cst.b Flag	; schon resident ?
	bne FResiX 
; nicht resident, dann:
; Autoordner-Start? 
	move.l #AutoTest,-(a7) 
	move #SupExe,-(a7) 
	trap #XBios 
	addq.l #6,a7 
	tst.b Auto 
	beq Normal 
	movea.1 #AText, a0 
	jsr Message 
	move.l #SetDOS,-(a7)
	move #SupExe,-(a7) 
	trap #XBios 
	addq.l #6,a7 
	bra.s ResEnd 
Normal
; neuen GEM-Trap und GemDos installieren 
	move.l #SetTraps,-(a7) 
	move #SupExe,-(a7) 
	trap #XBios 
	addq.l #6,a7
	jsr Key
ResEnd
; Programm resident lassen 
	clr.w -(a7) 
	move.l d6,-(a7) 
	move.w #Keep,-(a7) 
	trap #GemDos
;
FResiX ; war schon resident: 
	jsr Key 
; Commandline "~"? 
	move.b (a6),d0 
	cmpi.b #"~",d0 
	bne FResi
; Traps zurücksetzen 
	move.l #ResetTraps,-(a7) 
	move #SupExe,-(a7)
	trap #XBios 
	addq.l #6,a7 
FResi ; normal beenden 
	clr -(a7) 
	trap #GemDos
;
SetDOS 
	move.l 136,OldTrap 
	bra.s SetDOS2 
SetTraps 
	move.l 136,OldTrap 
	move.1 #GemTrap2,136 
SetDOS2 
	move.l 132,GemDosTrap 
	move.l #Trap1,132 
	rts
ResetTraps 
	move.1 OldTrap,136 
	move.1 GemDosTrap,132 
	rts 
GetTrap 
	move.l 136,a0 
	rts 
AutoTest 
	movem.l d0/d2/a0,-(a7) 
	clr.b d2
	movea.l FontBase,a0 
	move.l 76(a0),d0 
	tst.l d0 
	bne.s ExAuto 
	move.b #$ff,d2 
ExAuto 
	move.b d2,Auto 
	movem.l (a7)+,d0/d2/a0 
	rts
;
FontLaden
; Commandline "#" oder "~"? 
	move.b (a6),d0 
	cmpi.b #"~",d0 
	beq.s SysAdresse 
	move.b (a6),d0 
	cmpi.b #"#",d0 
	bne.s Laden 
SysAdresse
; ja: Systemfontadresse in a4 
; und Laden beenden 
	movea.l OldFont,a4 
	bra LEnde 
Laden 
	move.b (a6),d0
	cmpi.b #"-",d0	; - am Anfang
	bne.s DiskDa 
; ja: Warten und Disk prüfen 
	lea InsertDisk,a0 
	bsr Message 
	bsr Key 
	addq.l #1,a6 
	move.l #FontData,-(a7) 
	move #FSetDTA,-(a7) 
	trap #GemDos 
	addq.l #6,a7 
	move #31,-(a7) 
	move.l #Dummy,-(a7) 
	move #FSFirst,-(a7) 
	trap #GemDos 
	adda.l #8,a7
;
DiskDa
; Commandline leer —> Default-Datei "SYSFONT.FNT"
	move.b -1(a6),d0 
	tst.b d0 
	bne.s NameOk 
	move.l #Default,a6 
NameOk
; Datei öffnen 
	move.w #0,-(a7) 
	move.l a6,-(a7) 
	move.w #FOpen,-(a7) 
	trap #GemDos 
	addq.l #8,a7 
	move.l d0,d1 
	lea NoFile,a0 
	tst d0 
	bmi Error 
; Länge bestimmen 
	move #2,-(a7) 
	move d1,-(a7) 
	clr.l -(a7) 
	move #FSeek,-(a7) 
	trap #GemDos 
	adda.l #10,a7 
	lea WrongSize,a0 
	cmpi.l #4096,d0 
	bne ClError 
	move #0,-(a7) 
	move d1,-(a7) 
	clr.l -(a7) 
	move #FSeek,-(a7) 
	trap #GemDos 
	adda.l #10,a7
;
; Datei etwas "verdreht" einladen 
	clr.l d2 
Zeichen 
	clr.w d3 
Bits 
	clr.l d4 
	movea.l a4,a5 
	move.w d3,d4 
	asl.w #8,d4 
	add.l d2,d4 
	adda.l d4,a5 
	move.l a5,-(a7) 
	move.l #1,-(a7) 
	move.w d1,-(a7) 
	move.w #FRead,-(a7) 
	trap #GemDos 
	adda.l #12,a7 
	add.w #1,d3 
	cmpi.w #16,d3 
	bne.s Bits 
	add.l #1,d2 
	cmpi.l #256,d2 
	bne.s Zeichen 
; Datei schlie_en 
	move.w d1,-(a7) 
	move.w #FClose,-(a7) 
	trap #GemDos 
	addq.l #4,a7 
LEnde 
	rts
;
Trap1	; neuer	GemDos-Trap
	movem.l d0/d1/a0,-(a7) 
	tst.b Auto 
	beq TNormal 
	move.1 FontBase,a0 
	move.l 76(a0),d0 
	tst.l d0 
	beq TrapOk 
	bsr Autoinst 
	bra TrapOk 
TNormal 
	move.1 136,d0 
	cmpi.l #$FC0000,d0 
	bgt.s ChngTrap 
	move.l $4f2,d1 
	cmp.l d1,d0 
	blt.s TrapOk 
	move.l $4fa,d1 
	cmp.l d1,d0 
	bgt.s TrapOk 
ChngTrap
; GEM-Trap im TOS —> ändern 
	move.1 #GemTrap2,136
TrapOk 
	movem.l (a7)+,d0/d1/a0 
	move.l GemdosTrap,a0 
	jmp(a0)
;
Autoinst 
	move.l 136,O1dTrap 
	move.l #GemTrap2,136 
	clr.b Auto 
	movea.l FontBase,a0 
	move.l 76(a0),OldFont
	move.l FontAdr,76(a0)	; Adresse eintragen
	rts
;
OldTrap 
	dc.l 0 
GemDosTrap 
	dc.l 0 
FontAdr 
	dc.l 0 
OldFont
	dc.l 0 
	dc.b "Lutz"
GemTrap2 ; neuer GEM-Trap 
	cmpi.b #$73,d0	; VDI	?
	bne.s JumpGEM 
	movem.l d0-d2/a0-a5,-(a7) 
	movea.l d1,a4	; a4 zeigt auf VDIPB
	movea.l (a4),a5	; a5 zeigt auf Contrl-Feld
	cmpi.w #5,(a5)	; Escape-Funktion ?
	bne.s ContGEM
	cmpi.w #102,10(a5) ; Font anmelden ?
	bne.s ContGEM
	movea.l 4(a4),a5	; a5 zeigt jetzt auf Intin-Array
; Font-Adressen bestimmen 
	dc.w $A000
	move.l 8(a1),d2	; -> TOS-Font
	movea.l 4(a1),a3
	movea.l 84(a3),a3	; —> GEM-Font
	cmp.l d2,(a5)	; TOS-Font anmelden?
	bne.s ContGEM
	move.l a3,(a5)	; ... dann GEM-Font anmelden.
ContGEM 
	movem.l (a7)+,d0-d2/a0-a5 
JumpGEM 
	move.l OldTrap,a0 
	jmp(a0)
;
; String ausgeben 
Message 
	move.l a0,-(a7) 
	move #9,-(a7) 
	trap #GemDos 
	addq.l #6,a7 
	rts
; Auf Tastendruck warten 
Key
	move #7,-(a7) 
	trap #GemDos 
	addq.l #2,a7 
	rts
; Fehlerbehandlung...
ClError 
	movea.l a0,a6 
; Datei schlie_en 
	move d1,-(a7) 
	move #FClose,-(a7) 
	trap #GemDos 
	addq.l #4,a7 
	movea.l a6,a0 
Error 
	bsr.s Message 
	bsr.s Key
; Programm normal beenden 
	clr -(a7) 
	trap #GemDos 
End 
.data
Ok dc.b "Neuer Zeichensatz installiert. (LPSoft,1987)", 7,13,10,0 
Sys dc.b "Original Systemzeichensatz wieder angemeldet.",7,13,10,0 
NoFile dc.b "Fontdatei nicht vorhanden !!!", 7,13,10,0 
WrongSize dc.b "Datei hat nicht das richtige Fontformat" 
dc.b " (falsche Länge) ! !!", 7,13,10,0
WrongRes dc.b "Programm läuft nur in hoher Auflösung ! ! ! ", 7,13,10,0 
InsertDisk dc.b "Bitte Diskette einlegen.",7,13,10,0 
Info dc.b "STAD-Font als neuen 8x16 GEM- und TOS-Systemzeichensatz" 
dc.b" installieren.",13,10
dc.b "(c)	1987 by LPSoft, Lutz Pre_ler, Ahornweg 11,"
dc.b" 2904 Hatten",13,10,0 
Exit dc.b 13,10,"ANWENDUNG:	FONTINST.TTP DATEINAM.FNT " 
dc.b "DATEINAM.FNT installieren.",13,10 
dc.b " oder FONTINST.TTP # Originalzeichensatz" 
dc.b " wieder anmelden.",13,10,7,0 
NichtResiT dc.b "Programm nicht mehr resident.",13,10,0 
Dummy dc.b "\*.*", 0 
Default dc.b "SYSFONT.FNT",0
AText dc.b "Aus AUTO-Ordner gestartet.",13,10 
.even 
.bss
;
FontBase ds. 1 1 
TAuto ds.1 1 
Auto ds.w 1
FontData ds.b 4096	; Datenbereich	für	Font
; bis hier hin resident
Text ds.l 1	; Textadresse (Ok oder Sys)
Flag ds.w 1	; "resident"-Flag
;
PrgEnd

Lutz Preßler
Aus: ST-Computer 04 / 1988, Seite 14

Links

Copyright-Bestimmungen: siehe Über diese Seite