diff --git a/COMPILE.BAT b/COMPILE.BAT new file mode 100644 index 0000000..f7ed6c1 --- /dev/null +++ b/COMPILE.BAT @@ -0,0 +1 @@ +c:\progs\tp\tpc textgraf.pas \ No newline at end of file diff --git a/TEXTGRAF.PAS b/TEXTGRAF.PAS new file mode 100644 index 0000000..118cd7c --- /dev/null +++ b/TEXTGRAF.PAS @@ -0,0 +1,323 @@ + unit TextGraf; +interface +uses dos; +type + MonitorTyp = (Hercules, EGA, VGA, other); + VGAColorInfo = array[0..2] of byte; { eine VGA-Farbe: nur fr Demo } + VGAColors = array[0..255] of VGAColorInfo; { alle VGA-Farben: dito } + + function InitTextGraf: integer; + { Muá ganz zu Anfang des Programms, noch im Textmodus aufgerufen + werden. Ohne das funktioniert der Rest nicht. Ergebnis 0: Alles Ok, + unbekannter Videotyp: -1, zuwenig Speicher: 1 (Bedarf ca. 12Kb) } + procedure SetPaletteSave(On: boolean); + { Mit On = true nach InitTextGraf und im Textmodus aufrufen. Sichert die + Textpalette und reserviert Speicher fr die Grafikpalette, die dann + automatisch verwendet werden. On = false schaltet diese Automatik + wieder ab und gibt den Speicher fr die Paletten (ca. 1.5Kb) frei.} + procedure ToText; + { Schaltet vom Grafik- in den Testmodus. Bildspeicher etc. werden in + Sicherheit gebracht } + procedure ToGraph; + { Schaltet in die Grafik zurck. Vorher sollte ein Grafikmodus mit + ToText verlassen worden sein, um alle Werte zu initialisieren } + + procedure GrafikMode(Mode: byte); + { nur fr das Demoprogramm. Kann gel”scht werden, wenn BGI-Routinen + (InitGraph) verwendet werden } + function GetMonTyp: MonitorTyp; + { dito } + procedure SetVGAColors(var Colors: VGAColors); + { dito } +implementation + + +type + ScreenArray = array[0..3999] of word; { Bildspeicher bei 80x25 } + CharGenArray = array[0..8191] of byte; { Zeichengenerator } + ModeType = (Text, Grafik, unknown); + +var + regs: registers; { fr intr } + CharGen: CharGenArray absolute $A000:0; { Adresse Zeichengenerator } + BMode: byte absolute $40:$49; { Bios-Videomode } + +const + VModus: ModeType = unknown; + VMonitor: MonitorTyp = other; { Vorgabe: nichts gutes } + TScreen: ^ScreenArray = nil; { zeigt in den Bildspeicher } + ScrBuf: ^ScreenArray = nil; { speichert Textschirm zwischen } + CGBuf: ^CharGenArray = nil; { speichert Zeichengenerator } + ModeNr: byte = $FF; { Kennung fr Init } + TMode: byte = $FF; { der zu restaurierende Textmodus } + GMode: byte = $FF; { dito Grafikmodus } + VGATextPal: ^VGAColors = nil; + VGAGraphPal: ^VGAColors = nil; + +function IsVga: boolean; { haben wir VGA } +begin + with regs do + begin + AX:= $1A00; { Display Combination abfragen } + Intr($10, regs); + IsVga:= (AL = $1A); { gltiger Aufruf } + end; +end; + +function IsEGA: boolean; { liegt wenigstens EGA vor } +begin + with regs do + begin + AH:= $12; { Funktion $12 } + BL:= $10; { get EGA Information } + Intr($10, regs); + IsEga:= (BL <> $10); { hat sich was ge„ndert ? } + end; +end; + +procedure GetVGAColors(var Colors: VGAColors); +begin + with regs do + begin + ax:= $1017; + bx:= 0; + cx:= 255; + es:= seg(Colors); + dx:= ofs(Colors); + intr($10, regs); + end; +end; + +procedure SetVGAColors(var Colors: VGAColors); +begin + with regs do + begin + ax:= $1012; + bx:= 0; + cx:= 255; + es:= seg(Colors); + dx:= ofs(Colors); + intr($10, regs); + end; +end; + +procedure NoInitStop; +begin + writeln('TextGraph ist nicht initialisiert! Benutzen Sie InitTextGraph!'); + halt(2); +end; + +procedure HercTextMode; +var i: integer; + ModeReg: byte absolute 0:$465; +const HData: array[0..13] of byte = { Timingdaten! Nicht ver„ndern! } + ($61,$50,$52,$0f,$19,$06,$19,$19,$02,$0d,$0b,$0c,0,0); +begin + port[$3bf]:= 0; { Config Reg: HalfMode: eine Seite (3 fr Full Mode) } + port[$3b8]:= $21; { Mode Control: Dunkel, Text, 80x25 } + for i:= 0 to 13 do { die Timing-Daten komplett } + begin + port[$3b4]:= i; { Index Laden (Register einblenden) } + port[$3b5]:= HData[i]; { Wert schreiben } + end; + port[$3b8]:= $29; { ModeControl: Hell, Text, 80x25 } + ModeReg:= $29; { im BIOS-Ram protokollieren } +end; + +procedure HercGraphMode; +var i: integer; + ModeReg: byte absolute 0:$465; +const HData: array[0..13] of byte = { Timingdaten! Nicht ver„ndern! } + ($35,$2d,$2e,$07,$5b,$02,$57,$57,$02,$03,0,0,0,0); +begin + port[$3bf]:= 1; { Config Reg: HalfMode: eine Seite (3 fr Full Mode) } + port[$3b8]:= 2; { Mode Control: Dunkel, Grafik, Seite 0 } + for i:= 0 to 13 do { die Timing-Daten komplett } + begin + port[$3b4]:= i; { Index Laden (Register einblenden) } + port[$3b5]:= HData[i]; { Wert schreiben } + end; + port[$3b8]:= $0a; { ModeControl: Hell, Grafik, Seite 0 } + ModeReg:= $0a; { im BIOS-Ram protokollieren } +end; + +procedure GrafikMode(Mode: byte); { Setzt den Videomodus, nur fr Demo } +var i: integer; +begin + if VMonitor <> Hercules then { alle auáer Hercules sind sehr einfach } + with regs do + begin + AX:= Mode; { AH:= 0; AL:= Mode } + Intr($10, regs); + end + else + begin + HercGraphMode; + fillchar(ptr($B000,0)^, $8000, 0); { Clearscreen } + end; +end; + +function GetMonTyp: MonitorTyp; { Zugriffsfunktion, nur fr das Demo } +begin + GetMonTyp:= VMonitor; +end; + +procedure ToTextVGA; { sichert den Teil des Grafik-Bildspeichers, der } +var b: byte; { vom Zeichengenerator berschrieben wird } +begin + regs.ax:= $90; { Standardmodus setzen um Zugriff sicherzustellen } + intr($10, regs); { Bildspeicher bleibt erhalten } + Port[$3ce]:= 4; { Read Map Select holen } + b:= Port[$3cf]; { lesen } + Port[$3cf]:= 2; { Plane 2 ein } + CGBuf^:= CharGen; { Grafikinhalt von Zeichengenerator sichern } + Port[$3cf]:= b; { Wert zurck } +end; + +procedure ToTextEGA; { wie oben jedoch Variante fr EGA, } +var b: byte; { deren Register nicht lesbar sind } +begin + regs.ax:= $90; { Standardmodus setzen um Zugriff sicherzustellen } + intr($10, regs); { Bildspeicher bleibt erhalten } + Port[$3ce]:= 4; { Read Map Select holen } + Port[$3cf]:= 2; { Plane 2 ein } + CGBuf^:= CharGen; { Grafikinhalt von Zeichengenerator sichern } + Port[$3cf]:= 0; { Default zurck } +end; + +procedure ToGraphVGA; { berschreibt den Zeichengenerator mit } +var b: byte; { gesicherten Grafikinhalt } +begin + regs.ax:= $90; { Standardmodus setzen um Zugriff sicherzustellen } + intr($10, regs); { Bildspeicher bleibt erhalten } + Port[$3C4]:= 2; { Map Mask Register holen } + b:= Port[$3c5]; { lesen } + Port[$3c5]:= 4; { Plane 2 ein } + CharGen:= CGBuf^; { Zeichengenerator zurck } + Port[$3c5]:= b; { Wert zurck } +end; + +procedure ToGraphEGA; { wie oben jedoch Variante fr EGA, } +var b: byte; { deren Register nicht lesbar sind } +begin + regs.ax:= $90; { Standardmodus setzen um Zugriff sicherzustellen } + intr($10, regs); { Bildspeicher bleibt erhalten } + Port[$3C4]:= 2; { Map Mask Register holen } + Port[$3c5]:= 4; { Plane 2 ein } + CharGen:= CGBuf^; { Zeichengenerator kopieren } + Port[$3c5]:= 0; { Default zurck } +end; + +function InitTextGraf: integer; { ermittelt Monitor, setzt Variablen, } +begin { reserviert Speicher } + InitTextGraf:= 0; + if ModeNr <> $FF then exit; { wurde schon aufgerufen, alles ok } + InitTextGraf:= -1; { Fehlervorgabe: falsche Karte } + if IsEGA then VMonitor:= EGA; { EGA ? } + if IsVGA then VMonitor:= VGA; { oder VGA ? } + TMode:= BMode and $7f; + if TMode = 7 then + begin + TScreen:= ptr($B000,0); { Bildspeicheradresse Text mono setzen } + if VMonitor = other then { keines von beiden: } + begin + VMonitor:= Hercules; { dann Hercules, (evtl Probleme mit CGA-Mono)} + GMode:= 7; { Modi alle 7 } + end; + end else + TScreen:= ptr($B800,0); { Bildspeicheradresse Text farbig setzen } + if VMonitor = other then exit; { was anderes? geht nicht! } + InitTextGraf:= 1; { Fehlervorgabe: kein Speicher } + if VMonitor in [EGA, VGA] then + begin { Vorgaben fr EGA & VGA } + GMode:= $10; { Grafik 640x350 } + if MaxAvail >= sizeof(CGBuf) then { Speicher fr Puffer belegen } + New(CGBuf) + else + exit; { raus mit Fehler 1 } + end; + if MaxAvail >= sizeof(ScrBuf) then { noch mehr } + New(ScrBuf) + else + exit; { raus mit Fehler 1 } + ModeNr:= TMode; { Initialisierung merken } + InitTextGraf:= 0; { alles ok } +end; + +procedure SetPaletteSave(On: boolean); + { aktiviert oder deaktiviert die automatische Palettensicherung } +begin + if ModeNr = $FF then NoInitStop; { schon Init ? } + if On then + begin + if VGATextPal = nil then { gibts schon ? } + new(VGATextPal); { nein, neu } + if VGAGraphPal = nil then { dito Grafikpalette } + new(VGAGraphPal); + GetVGAColors(VGATextPal^); { Textfarben holen } + end else + begin + if VGATextPal <> nil then { was da ? } + begin + dispose(VGATextPal); { freigeben } + VGATextPal:= nil; { und kennzeichnen } + end; + if VGAGraphPal <> nil then { andere auch } + begin + dispose(VGAGraphPal); + VGAGraphPal:= nil; + end; + end; +end; + +procedure ToText; { Schaltet in Textmodus, bringt, was berschrieben } +begin { wird in Sicherheit } + if ModeNr = $FF then NoInitStop; { schon Init ? } + GMode:= BMode; { Grafikmodus merken } + case VMonitor of + VGA: begin + if VGAGraphPal <> nil then + GetVGAColors(VGAGraphPal^); + ToTextVGA; { Zeichengeneratorbereich sichern } + end; + EGA: ToTextEGA; + end; {case} + if VMonitor = Hercules then + HercTextMode { Hercules Textmodus ohne Bildspeicher l”schen } + else + begin + regs.ax:= TMode or $80; { Text, Bit 7 = 1: Bildspeicher nicht l”schen } + intr($10, regs); + if (VMonitor = VGA) and (VGATextPal <> nil) then + SetVGAColors(VGATextPal^); + end; + scrbuf^:= TScreen^; { Grafikinhalt von Textschirm sichern } + VModus:= Text; +end; + +procedure ToGraph; { versucht den Grafikmodus zu restaurieren } +begin + if ModeNr = $FF then NoInitStop; { schon Init ? } + TMode:= BMode; + TScreen^:= ScrBuf^; { Grafikinhalt zurck in Textbildschirm fllen } + case VMonitor of + VGA: begin + if VGATextPal <> nil then + GetVGAColors(VGATextPal^); + ToGraphVGA; { dito Zeichengenerator } + end; + EGA: ToGraphEGA; + end; {case} + if VMonitor = Hercules then + HercGraphMode { Hercules handmade Grafikmodus } + else + begin + regs.ax:= GMode or $80; { Text, Bit 7 = 1: Bildspeicher nicht l”schen } + intr($10, regs); + if (VMonitor = VGA) and (VGAGraphPal <> nil) then + SetVGAColors(VGAGraphPal^); + end; + VModus:= Grafik; +end; + +end. diff --git a/TEXTGRAF.TPU b/TEXTGRAF.TPU new file mode 100644 index 0000000..53681bd Binary files /dev/null and b/TEXTGRAF.TPU differ