home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* PASSCR.PAS *)
- (* Bildschirm-Sicherung/-Restaurierung mit Standard-Pascal *)
- (* Im Prinzip fuer jeden Pascal-Compiler und jeden Rechner anwendbar, so- *)
- (* fern die Organisation und Adresse des Bildschirmspeichers bekannt ist. *)
- (* Desweiteren muss eine Ueberwachung von Zeigern durch das Pascal Lauf- *)
- (* zeit-System abschaltbar sein, falls selbiges stattfinden sollte. *)
- (* Hier die Implementationen fuer Pascal ST Plus auf Atari ST sowie den *)
- (* MS-DOS Pascal-Compiler BCI-Pascal. Die nicht benoetigte Version v o r *)
- (* der Compilierung l o e s c h e n !! *)
-
- PROGRAM screendemo;
-
- (* Typen und Variablen an entsprechender Stelle im Programm (global) *)
- (* vereinbaren. Die Struktur des Bildschirmspeichers (VideoRam) ist *)
- (* systemabhaengig und muss entsprechend angepasst werden. Ebenso muss *)
- (* der Adresse-Type (hier LONG-INTEGER, entspricht der Darstellung von *)
- (* Zeigern auf dem ST, 2 Worte) dem System angepasst werden - die meisten *)
- (* MS-DOS Pascal-Compiler kennen keine LONG-Integers - also z.B. ein *)
- (* Record mit Segment und Offset vom Typ Integer verwenden. *)
- (* ----------------------------------------------------------------------- *)
- (* fuer Atari ST und Pascal ST Plus: *)
- TYPE
- VideoRam = ARRAY [1..400,1..20] OF LONG_INTEGER; (* 32 kByte *)
- ScreenPtr = RECORD CASE BOOLEAN OF (* der CASE-Trick *)
- FALSE: (VideoAdr: LONG_INTEGER);
- TRUE : (VideoMem: ^VideoRam);
- END;
-
- VAR (* fuer die Demonstration *)
- ScreenBuffer: ScreenPtr; i: INTEGER; ch: CHAR;
- (* ----------------------------------------------------------------------- *)
- (* Adresse des aktiven Bildschirmspeichers ermitteln: *)
- FUNCTION LogScreenBase: LONG_INTEGER; XBios(3);
- (* ----------------------------------------------------------------------- *)
- (* Bildschirm sichern: *)
- PROCEDURE SaveScreen (VAR Screen: ScreenPtr);
- VAR LogScreen: ScreenPtr;
- BEGIN
- New(Screen.VideoMem); (* neuen Bildschirmspeicher dynamisch anlegen *)
- LogScreen.VideoAdr := LogScreenBase;
- (*$P-*) (* Ueberwachung von Zeigern durch Laufzeitsystem abschalten *)
- (* folgende Zuweisung erledigt die ganze Maloche - und das recht flott: *)
- Screen.VideoMem^ := LogScreen.VideoMem^;
- (*$P=*) (* vorherigen Zustand d. Compiler-Option wieder herstellen *)
- END;
- (* ----------------------------------------------------------------------- *)
- (* Bildschirm restaurieren: *)
- PROCEDURE RestoreScreen (VAR Screen: ScreenPtr);
- VAR LogScreen: ScreenPtr;
- BEGIN
- LogScreen.VideoAdr := LogScreenBase; (* dito! *)
- (*$P-*)
- LogScreen.VideoMem^ := Screen.VideoMem^;
- (*$P=*)
- Dispose(Screen.VideoMem); (* dynam. Bildschirmspeicher wieder freigeben *)
- END;
- (* ----------------------------------------------------------------------- *)
- (* ----------------------------------------------------------------------- *)
- (* fuer MS-DOS und BCI-Pascal: *)
-
- (*$Z+*) (* "long pointers" um Bildschirmspeicher zu adressieren *)
- TYPE
- BYTE = 0..255;
- VideoRam = ARRAY[1..2000,1..2] OF BYTE; (* character, attribute, 4000 B.*)
- ScreenPtr = RECORD CASE BOOLEAN OF (* ebenfalls der CASE-Trick *)
- FALSE: (VideoSeg, VideoOfs: INTEGER);
- TRUE : (VideoMem: ^VideoRam);
- END;
-
- VAR (* fuer die Demonstration *)
- ScreenBuffer: ScreenPtr; i: INTEGER; ch: CHAR;
- (* ----------------------------------------------------------------------- *)
- (* Adresse des aktiven, angezeigten Bildschirmspeichers ermitteln: *)
- FUNCTION LogScreenBase: ScreenPtr;
- BEGIN (* hier einfach die Konstanten fuer CGA: *)
- LogScreenBase.VideoSeg := 0B800h; LogScreenBase.VideoOfs := 0000h;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Bildschirm sichern: *)
- PROCEDURE SaveScreen (VAR Screen: ScreenPtr);
- VAR LogScreen: ScreenPtr;
- BEGIN
- New(Screen.VideoMem); (* neuen Bildschirmspeicher dynamisch anlegen *)
- LogScreen := LogScreenBase;
- (* folgende Zuweisung erledigt die ganze Maloche - und das recht flott: *)
- Screen.VideoMem^ := LogScreen.VideoMem^;
- END;
- (* ----------------------------------------------------------------------- *)
- (* Bildschirm restaurieren: *)
- PROCEDURE RestoreScreen (VAR Screen: ScreenPtr);
- VAR LogScreen: ScreenPtr;
- BEGIN
- LogScreen := LogScreenBase; (* dito! *)
- LogScreen.VideoMem^ := Screen.VideoMem^;
- Dispose(Screen.VideoMem); (* dynam. Bildschirmspeicher wieder freigeben *)
- END;
- (* ----------------------------------------------------------------------- *)
- (* ----------------------------------------------------------------------- *)
- (* und die Demonstration: *)
-
- BEGIN (* screendemo *)
- FOR i := 1 TO 2000 DO Write('A'); (* Bildschirm mit 'A' fuellen... *)
- SaveScreen(ScreenBuffer); (* Inhalt des selbigen sichern... *)
- Write('RETURN druecken...'); ReadLn(ch); (* auf RETURN warten *)
- FOR i := 1 TO 25 DO WriteLn; (* und jetzt den Bildschirm loeschen *)
- Write('RETURN druecken...'); ReadLn(ch);
- RestoreScreen(ScreenBuffer); (* alten Bildschirm wieder zeigen... *)
- Write('RETURN druecken...'); ReadLn(ch);
- END.
-