TUI programmieren [C]

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Sooo. Ich habe keine weiteren Bugs gefunden. Textareas sollten also funktioniern.
Jetzt mach ich erstmal nen Tag oder zwei Pause und dann kommt:

- Ladebalken
- Fenster schließen/minimieren
- allwaysOnTop und so ein Kram
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ich wollte jetzt schonmal fragen, weil das bestimmt noch kommt:

Wie kann die Zeichen im BIOS editieren?
Also anstatt A soll da z.B. ein kleines Haus sein oder sowas.
Ich wollte auf diese Weise die nicht-druckbaren Zeichen editieren, da man die ja trotzdem in die VIDEO-RAM schreiben kann. So könnte ich erreichen, dass man ein Symbol für ein Laufwerk oder ein Symbol für eine Datei oder sowas. Ihr versteht hoffentlich was ich meine.

Jetzt interessiert mich, wie ich das machen kann. Und auch, wie ich das während der Laufzeit rückgängig machen kann. Außerdem möchte ich sowohl die Font für 80x25 als auch für 80x50 editieren können. ich weiß, dass es geht, ich hab das iwo mal gesehen.

Und ich weiß auch, dass frecrac mir jetzt bestimmt einen langen Assembly-code zeigen wird, der das tut (bzw. ich hoffe es. auch wenn mir C mehr liegt)
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: TUI programmieren [C]

Beitrag von DOSferatu »

Könnte Dir mal schnell n Code zusammenmeißeln. Benutze das z.B. in meinem Pirate-Chat (und einigen anderen Tools).
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Das wäre super =)
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Ich wollte jetzt schonmal fragen, weil das bestimmt noch kommt:

Wie kann die Zeichen im BIOS editieren?
Also anstatt A soll da z.B. ein kleines Haus sein oder sowas.
Ich wollte auf diese Weise die nicht-druckbaren Zeichen editieren, da man die ja trotzdem in die VIDEO-RAM schreiben kann. So könnte ich erreichen, dass man ein Symbol für ein Laufwerk oder ein Symbol für eine Datei oder sowas. Ihr versteht hoffentlich was ich meine.

Jetzt interessiert mich, wie ich das machen kann. Und auch, wie ich das während der Laufzeit rückgängig machen kann. Außerdem möchte ich sowohl die Font für 80x25 als auch für 80x50 editieren können. ich weiß, dass es geht, ich hab das iwo mal gesehen.

Und ich weiß auch, dass frecrac mir jetzt bestimmt einen langen Assembly-code zeigen wird, der das tut (bzw. ich hoffe es. auch wenn mir C mehr liegt)
Diesmal muss ich dich entäuschen, denn zuletzt habe ich so etwas auf dem C64er gemacht. Auf dem PC wollte ich es zwar auch schon machen, ich bin aber noch nie dazu gekommen.
Nun habe ich folgende Interrupts dafür gefunden, mir ist es aber nicht so ganz klar wo die genauen Unterschiede hierbei sind.
Man beginnt wohl damit einen Videomode einzuschalten und übergibt danach einen Zeiger(in ES:BP) auf die eigene Font-Tabelle.

Code: Alles auswählen

RBIL->inter61a.zip->INTERRUP.A
--------V-101100-----------------------------
INT 10 - VIDEO - TEXT-MODE CHARGEN - LOAD USER-SPECIFIED PATTERNS (PS,EGA,VGA)
	AX = 1100h
	ES:BP -> user table
	CX = count of patterns to store
	DX = character offset into map 2 block
	BL = block to load in map 2
	BH = number of bytes per character pattern
Return: nothing
Notes:	This function will cause a mode set, completely resetting
	  the video environment, but without clearing the video buffer
	the current block specifiers may be determined with INT 10/AH=1Bh,
	  looking at offsets 2Bh and 2Ch of the returned data (VGA only)
	  (see AH=1Bh,#00040)
SeeAlso: AX=1101h,AX=1102h,AX=1103h,AX=1104h,AX=1110h,AH=1Bh,AX=CD10h
SeeAlso: MEM 0040h:0084h
Index:	text mode;font|text mode;screen rows
--------V-101110-----------------------------
INT 10 - VIDEO - TEXT-MODE CHARGEN - LOAD USER-SPECIFIED PATTERNS (PS,EGA,VGA)
	AX = 1110h
	ES:BP -> user table
	CX = count of patterns to store
	DX = character offset into map 2 block
	BL = block to load in map 2
	BH = number of bytes per character pattern
Return: nothing
Notes:	This function will cause a mode set, completely resetting
	  the video environment, but without clearing the video buffer
	This function is designed to be called immediately after a mode set,
	  it is equivalent to AX=110xh except that:
	      Page 0 must be active.
	      Bytes/character is recalculated.
	      Max character rows is recalculated.
	      CRT buffer length is recalculated.
	      CRTC registers are reprogrammed as follows:
		     R09 = bytes/char-1 ; max scan line (mode 7 only)
		     R0A = bytes/char-2 ; cursor start
		     R0B = 0		; cursor end
		     R12 = ((rows+1)*(bytes/char))-1 ; vertical display end
		     R14 = bytes/char	; underline loc
			   (*** BUG: should be 1 less ***)
	the current block specifiers may be determined with INT 10/AH=1Bh,
	  looking at offsets 2Bh and 2Ch of the returned data (VGA only)
	  (see AH=1Bh,#00040)
SeeAlso: AX=1100h,AX=1111h,AX=1112h,AX=1114h,AH=1Bh,AX=CD10h,MEM 0040h:0084h
Index:	text mode;font|text mode;screen rows
--------V-101120-----------------------------
INT 10 - VIDEO - GRAPH-MODE CHARGEN - SET USER 8x8 GRAPHICS CHARS (PS,EGA,VGA)
	AX = 1120h
	ES:BP -> user table for INT 1F
Return: nothing
Note:	this function is meant to be called immediately after a mode set;
	  results are unpredictable at other times
SeeAlso: AX=1121h,AX=1122h,AX=1123h,AX=1124h,AX=1129h,INT 1F"SYSTEM DATA"
SeeAlso: INT 43"VIDEO DATA"
--------V-101121-----------------------------
INT 10 - VIDEO - GRAPH-MODE CHARGEN - SET USER GRAPHICS CHARACTERS (PS,EGA,VGA)
	AX = 1121h
	ES:BP -> user table
	CX = bytes per character
	BL = row specifier
	    00h user set
		DL = number of rows
	    01h 14 rows
	    02h 25 rows
	    03h 43 rows
Return: AL = new number of rows (Diamond Stealth64 Video)
Note:	this function is meant to be called immediately after a mode set;
	  results are unpredictable at other times
SeeAlso: AX=1120h,AX=1122h,AX=1123h,AX=1124h,AX=1129h"Compaq"
SeeAlso: AX=1129h"Diamond",INT 1F"SYSTEM DATA",INT 43"VIDEO DATA"
Vor dem Beenden der Anwendung muss natürlich wieder auf die ursprüngliche Tabelle zurückgeschaltet werden, wenn die Tabelle nicht resident(siehe INT 27h) im Speicher verbleiben soll.
Ob es für das Zurückschalten auf die ursprüngliche Tabelle genügt, wenn man z.B. über "INT 10h, 1114h" (LOAD ROM 8x16 CHARACTER SET) aufruft, weiss ich nicht genau.

Code: Alles auswählen

--------V-101112-----------------------------
INT 10 - VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x8 DBL-DOT PATTERNS (PS,EGA,VGA)
	AX = 1112h
	BL = block to load
Return: nothing
Notes:	(see AX=1110h)
SeeAlso: AX=1103h,AX=1110h,AX=1111h,AX=1114h,AH=1Bh,AX=CD10h
--------V-101114-----------------------------
INT 10 - VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x16 CHARACTER SET (VGA)
	AX = 1114h
	BL = block to load
Return: nothing
Notes:	(see AX=1110h)
SeeAlso: AX=1104h,AX=1110h,AX=1111h,AX=1112h,AH=1Bh,AX=CD10h
Wenn das nicht genügt, dann könnte man aber bei der Verwendung von "SET USER 8x8 GRAPHICS CHARS" die vorherige Adresse vom Vector 1Fh(siehe Adresse 1Fh*4) die man sich gerettet hat wieder restaurieren.

Dirk
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

ich warte erstmal auf Dosferatu.
Dann werd ich euch sagen, wie ichs mach =)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Gut...
Hab jetzt nix gutes mehr gefunden...
Steht eig. iwo mal genau, wo gewisse sachen in der RAM liegen? also ganz genau. Jede einzelne Tabelle. Das über interupts zu regeln is immer iwi komisch in C, finde ich. Aber wenn von Dosferatu nichts mehr kommen sollte, werde ich es so machen.

Das tolle an dem Projekt ist, dass man da überall an allen themen basteln kann xD
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Re: TUI programmieren [C]

Beitrag von Dosenware »

Worum gehts? Daten (z.b. der Bildschirmspeicher A000-BFFF = Grafik+Text+Monochrom) oder die Routinen?

Bei den Routinen koennte es schwierig werden:
Der Speicherort Interrupttabelle müsste sich im Netz irgendwo finden lassen, die musst du auslesen um die Sprungadressen fuer die eigentlichen Interrupthandler zu bekommen - wie du an deine Routine herankommst wenn es fuer einen IRQ mehrere Handler gibt kann ich dir allerdings nicht sagen - wird aber aufwendig.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: TUI programmieren [C]

Beitrag von DOSferatu »

Also gut. Ich poste hier mal, wie man ein Zeichen setzt oder holt - und zwar mit VGA-Registern (ohne INTs). Ich habe das nicht selbst herausgefunden, sondern mal irgendwann aus der SWAG geholt (und etwas umgeschrieben).
Befindet man sich im Textmode, liegen die Zeichensätze ab $A000:$0000 im Speicher. (Zeichensätze? Ja, man kann mehrere unterbringen, zwischen denen man umschalten kann. Es gibt sogar die Möglichkeit, 512 Zeichen gleichzeitig zu haben, dann hat man nur noch 8 "Vordergrund"-Farben (weil das eine Bit
- also bit 3 - als Bit 8 der Zeichennummer benutzt wird.

Das Zeugs hier ist also in PASCAL.

Code: Alles auswählen

{Setzt neues Zeichen}
procedure SetChar(Nr:byte;var Data;Size:byte);
var Offset : Word;
begin
Offset:=word(Nr)shl 5; Inline($FA);{=CLI}
PortW[$3C4] := $0402; PortW[$3C4] := $0704;
PortW[$3CE] := $0204; PortW[$3CE] := $0005;
PortW[$3CE] := $0006;
move(Data,mem[$A000:offset],size);
PortW[$3C4] := $0302; PortW[$3C4] := $0304;
PortW[$3CE] := $0004; PortW[$3CE] := $1005;
PortW[$3CE] := $0E06;
Inline($FB);{=STI}
end;
Erklärung:
PortW[x]:=y; Setzt in Pascal an Port x das Low-Byte des Words y und danach an Port x+1
das Highbyte des Words y.
In Assembler wäre das, wenn DX der Port (also x) ist und AX die beiden Werte enthält (also y) :

Code: Alles auswählen

out DX,AX
Diese Port-Befehle an die Grafikkarte sind nötig, um den Zugriff auf den Speicher freizuschalten. In Wirklichkeit ist das ja nicht die Adresse $A000:$0000, sondern irgendwo anders in der Grafikkarte, aber die wird nunmal über $A000:$0000 "eingeblendet". Danach muß man das Ganze natürlich wieder zurückschalten.

Zu beachten ist (die man an dem SHL 5 sieht) daß ein Zeichen IMMER 32 Bytes hat! Die Anzahl Zeichenzeilen die dann wirklich dargestellt werden, hängen von der Einstellung der Grafikkarte ab. D.h. Zeichen 0 beginnt an Adresse $A000:$0000, Zeichen 1 an Adresse $A000:$0020, Zeichen 2 an Adresse $A000:$0040.
Obige Routine setzt nur ein einzelnes Zeichen, man kann die 256 mal in einer Schleife aufrufen, um einen ganzen Zeichensatz zu setzen. Oder man modifiziert den in der Mitte enthaltenen Move-Befehl entsprechend. (Es ist halt so: Normalerweise hat man so ein Zeichensatz-File eben z.B. für 8x8-Pixel- oder 16x8-Pixel (oder 14x8 Pixel etc) Zeichen, ohne die unbenutzten Zeichenzeilen (Bytes) zwischen den einzelnen Zeichen. Daher muß man die Zeichen einzeln setzen. (Die Zeichenhöhe ist also maximal 32 Zeilen.)

Achja: Die beiden Inline(xx) Befehle fügen Bytes direkt in den Code ein. Das sind einmal $FA (für den Asm-Befehl CLI, um die Hardware-Interrupts kurzzeitig zu sperren) und einmal §FB (für den Asm-Befehl STI, um die Hardware-Interrupts wieder freizugeben).

Ich schreibe es nun nochmal in Assembler, falls jemand Pascal nicht so mag.
Voraussetzung sind, daß man einige Register auf die Werte setzt:

CX =Zeilenanzahl des Zeichens
DS:SI = Adresse des Zeichensatzes
DI = Nummer des Zeichens

Code: Alles auswählen

{Setzt neues Zeichen}
@SetChar:
  pushA         {Alle Register retten}
  push ES       {ES auch retten}
  and DI,$00FF  {Highbyte von DI loeschen - zur Sicherheit...}
  shl DI,5      {32 Zeilen pro Zeichen}
  mov AX,$A000  {Segment=$A000}
  mov ES,AX     {Nach ES}
  pushF         {Flags retten (weil Direction-Flag und Int-Flag geandert}
  cld           {Direction Flag auf "vorwaerts"}
  cli           {Interrupts sperren}
  mov DX,$03C4  {Port $03C4 der VGA}
  mov AX,$0402  {VGA-Register $02, Wert $04}
  out DX,AX     {...setzen}
  mov AX,$0704  {VGA-Register $04, Wert $07}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  mov AH,$02    {VGA-Register $04 (AL unverändert), Wert $02}
  out DX,AX     {...setzen}
  mov AX,$0005  {VGA-Register $05, Wert $00}
  out DX,AX     {...setzen}
  inc AL        {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  repnz movsb   {CX bytes von DS:SI nach ES:DI kopieren}
  mov DL,$C4    {Port $03C4 der VGA}
  mov AX,$0302  {VGA-Register $02, Wert $03}
  out DX,AX     {...setzen}
  mov AL,$04    {VGA-Register $04, Wert $03}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  xor AH,AH     {VGA-Register $04, Wert $00}
  out DX,AX     {...setzen}
  mov AX,$1005  {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  mov AX,$0E06  {VGA-Register $06, Wert $0E}
  out DX,AX     {...setzen}
  popF          {Flags zurueckholen auf vorige Werte}
  pop ES        {ES zurueckholen}
  popA          {Alle Register zurueckholen}
  ret           {Ruecksprung aus der Subroutine}
Geändert werden die Register ES,AX,CX,DX,SI,DI - daher hab ich da gleich mal (für alle außer ES) pushA/popA benutzt.
Ich hoffe, ich habe beim Assembler-Teil keinen Fehler gemacht - ich habe das einfach nur mal kurz in Asm umgesetzt, aber nicht getestet. Aber es ist ja, wie man sieht, keine Raketenwissenschaft, das würde wohl auch jeder (der etwas Asm kann) selbst hinkriegen.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Ich habe deinen Code jetzt mal so abgetippt, aber es wird nur jede zweite zeile übernommen. Der Rest bleibt vom Originalbuchstaben.
also 1Zeile mein buchstabe,1Zeile standard,1Zeile mein Buchstabe,1Zeile standard usw.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

Aber mit dem code hier:
http://www.dnd.utwente.nl/~tim/colorfor ... GA/VGA.ASM
damit gehts. also die wichtigen Teile davon.
Aber vielen Dank.

@Dosenware
Ne mich interessierte z.B. wo diese Font liegt. Sowas wird nirgens erklärt.
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

DOSferatu hat geschrieben:Also gut. Ich poste hier mal, wie man ein Zeichen setzt oder holt - und zwar mit VGA-Registern (ohne INTs). Ich habe das nicht selbst herausgefunden, sondern mal irgendwann aus der SWAG geholt (und etwas umgeschrieben).
Mit "SWAG" ist die "SourceWare Archive Group" gemeint?
http://www.bsdg.org/swag/index.html
Befindet man sich im Textmode, liegen die Zeichensätze ab $A000:$0000 im Speicher.
Es gibt aber auch Grafikmodi die eine Textausgabe unterstützen.
(Zeichensätze? Ja, man kann mehrere unterbringen, zwischen denen man umschalten kann. Es gibt sogar die Möglichkeit, 512 Zeichen gleichzeitig zu haben, dann hat man nur noch 8 "Vordergrund"-Farben (weil das eine Bit
- also bit 3 - als Bit 8 der Zeichennummer benutzt wird.
Aha, gut zu wissen. Ich habe mal gesucht und das hier gefunden:
http://guru-home.dyndns.org/Zeichensatz-verdoppeln.html
Das Zeugs hier ist also in PASCAL.

Code: Alles auswählen

{Setzt neues Zeichen}
procedure SetChar(Nr:byte;var Data;Size:byte);
var Offset : Word;
begin
Offset:=word(Nr)shl 5; Inline($FA);{=CLI}
PortW[$3C4] := $0402; PortW[$3C4] := $0704;
PortW[$3CE] := $0204; PortW[$3CE] := $0005;
PortW[$3CE] := $0006;
move(Data,mem[$A000:offset],size);
PortW[$3C4] := $0302; PortW[$3C4] := $0304;
PortW[$3CE] := $0004; PortW[$3CE] := $1005;
PortW[$3CE] := $0E06;
Inline($FB);{=STI}
end;
Erklärung:
PortW[x]:=y; Setzt in Pascal an Port x das Low-Byte des Words y und danach an Port x+1
das Highbyte des Words y.
In Assembler wäre das, wenn DX der Port (also x) ist und AX die beiden Werte enthält (also y) :

Code: Alles auswählen

out DX,AX
Diese Port-Befehle an die Grafikkarte sind nötig, um den Zugriff auf den Speicher freizuschalten. In Wirklichkeit ist das ja nicht die Adresse $A000:$0000, sondern irgendwo anders in der Grafikkarte, aber die wird nunmal über $A000:$0000 "eingeblendet". Danach muß man das Ganze natürlich wieder zurückschalten.
Kann man den User-Zeichesatz nicht an jede beliebige freie Speichstelle legen?

Zurückschalten auf die Adresse auf die 1Fh*4 zeigt?
Zu beachten ist (die man an dem SHL 5 sieht) daß ein Zeichen IMMER 32 Bytes hat! Die Anzahl Zeichenzeilen die dann wirklich dargestellt werden, hängen von der Einstellung der Grafikkarte ab. D.h. Zeichen 0 beginnt an Adresse $A000:$0000, Zeichen 1 an Adresse $A000:$0020, Zeichen 2 an Adresse $A000:$0040.
Obige Routine setzt nur ein einzelnes Zeichen, man kann die 256 mal in einer Schleife aufrufen, um einen ganzen Zeichensatz zu setzen. Oder man modifiziert den in der Mitte enthaltenen Move-Befehl entsprechend. (Es ist halt so: Normalerweise hat man so ein Zeichensatz-File eben z.B. für 8x8-Pixel- oder 16x8-Pixel (oder 14x8 Pixel etc) Zeichen, ohne die unbenutzten Zeichenzeilen (Bytes) zwischen den einzelnen Zeichen. Daher muß man die Zeichen einzeln setzen. (Die Zeichenhöhe ist also maximal 32 Zeilen.)
Warum genau braucht man solche Lücken zwischen den Zeichen?
Achja: Die beiden Inline(xx) Befehle fügen Bytes direkt in den Code ein. Das sind einmal $FA (für den Asm-Befehl CLI, um die Hardware-Interrupts kurzzeitig zu sperren) und einmal §FB (für den Asm-Befehl STI, um die Hardware-Interrupts wieder freizugeben).

Ich schreibe es nun nochmal in Assembler, falls jemand Pascal nicht so mag.
Voraussetzung sind, daß man einige Register auf die Werte setzt:

CX =Zeilenanzahl des Zeichens
DS:SI = Adresse des Zeichensatzes
DI = Nummer des Zeichens

Code: Alles auswählen

{Setzt neues Zeichen}
@SetChar:
  pushA         {Alle Register retten}
  push ES       {ES auch retten}
  and DI,$00FF  {Highbyte von DI loeschen - zur Sicherheit...}
  shl DI,5      {32 Zeilen pro Zeichen}
  mov AX,$A000  {Segment=$A000}
  mov ES,AX     {Nach ES}
  pushF         {Flags retten (weil Direction-Flag und Int-Flag geandert}
  cld           {Direction Flag auf "vorwaerts"}
  cli           {Interrupts sperren}
  mov DX,$03C4  {Port $03C4 der VGA}
  mov AX,$0402  {VGA-Register $02, Wert $04}
  out DX,AX     {...setzen}
  mov AX,$0704  {VGA-Register $04, Wert $07}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  mov AH,$02    {VGA-Register $04 (AL unverändert), Wert $02}
  out DX,AX     {...setzen}
  mov AX,$0005  {VGA-Register $05, Wert $00}
  out DX,AX     {...setzen}
  inc AL        {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  repnz movsb   {CX bytes von DS:SI nach ES:DI kopieren}
  mov DL,$C4    {Port $03C4 der VGA}
  mov AX,$0302  {VGA-Register $02, Wert $03}
  out DX,AX     {...setzen}
  mov AL,$04    {VGA-Register $04, Wert $03}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  xor AH,AH     {VGA-Register $04, Wert $00}
  out DX,AX     {...setzen}
  mov AX,$1005  {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  mov AX,$0E06  {VGA-Register $06, Wert $0E}
  out DX,AX     {...setzen}
  popF          {Flags zurueckholen auf vorige Werte}
  pop ES        {ES zurueckholen}
  popA          {Alle Register zurueckholen}
  ret           {Ruecksprung aus der Subroutine}
Geändert werden die Register ES,AX,CX,DX,SI,DI - daher hab ich da gleich mal (für alle außer ES) pushA/popA benutzt.
(Ich rette meistens nur jene Register deren Werte ich nach einem Aufruf einer Subroutine auch wirklich erneut benutzen möchte, bzw. wenn der Inhalt der Register nicht benötigt wird, dann braucht er auch nicht unnötig gepusht und gepoppt werden. Aber für so ein Beispiel ist es natürlich wichtig auf alle begleitenden Umstände hinzuweisen.)
Ich hoffe, ich habe beim Assembler-Teil keinen Fehler gemacht - ich habe das einfach nur mal kurz in Asm umgesetzt, aber nicht getestet. Aber es ist ja, wie man sieht, keine Raketenwissenschaft, das würde wohl auch jeder (der etwas Asm kann) selbst hinkriegen.
Es sieht gut aus, einen Fehler konnte ich nicht entdecken.

......

http://webpages.charter.net/danrollins/ ... p/0091.HTM
Programming for Direct Access to Character Generator RAM
The following sequence sets up the EGA and VGA for accessing character-
generator memory. See EGA I/O Ports for related information.

out 3c4H, 0402H Mask reg; enable write to map 2
out 3c4H, 0704H Memory Mode reg ; alpha, ext mem, non-interleaved
out 3ceH, 0005H Graphics Mode reg; non-interleaved access
out 3ceH, 0406H Graphics Misc reg; map char gen RAM to a000:0
out 3ceH, 0204H Graphics ReadMapSelect reg; enable read chargen RAM

After these OUTs, the font data begins at a000:0 and the first byte of
font data for a character begins at the character's ASCII value * 32.
After reading or writing the font data, the following sequence restores
the EGA/VGA to normal operations:

out 3c4H, 0302H Mask reg; disable write to map 2
out 3c4H, 0304H Memory Mode reg; alpha, ext mem, interleaved
out 3ceH, 1005H Graphics Mode reg; interleaved access
out 3ceH, 0e06H Graphics Misc reg; regen buffer to b800:0
out 3ceH, 0004H Graphics ReadMapSelect reg; disable read chargen RAM

.....................................................

Besonders leicht ist es ja nicht die Funktionsweise der verschiednen VGA-Register zu erkennen.
Um einen Überblick der Portadressen der VGA-Register zu bekommen:
RBIL->inter61d.zip->PORTS.B

EGA/VGA - ATTRIBUTE CONTROLLER

Code: Alles auswählen

--------V-P03C003C1--------------------------
PORT 03C0-03C1 - EGA/VGA - ATTRIBUTE CONTROLLER
Range:	PORT 03C0h or PORT 02C0h (alternate EGA)
SeeAlso: PORT 03C2h,PORT 03D0h,#P0718

03C0  rW  ATC index/data register
		Every write access to this register will toggle an internal
		  index/data selection flipflop, so that consecutive writes to
		  index & data is possible through this port. To get a defined
		  start condition, each read access to the input status register
		  #1 (3BAh in mono / 3DAh in color) resets the flipflop to load
		  index. If values are changed during the vertical retrace
		  period only no flicker will occur.

		index register (flipflop reset to 'index'): (default 20h)
		  bit7-6: reserved
		  bit5	: 0=CPU access (screen dark),
			  1=video access to registers
		  bit4-0: index in ATC (0..31)

		indexed registers in ATC (flipflop set to 'data'): (see #P0662)
03C1  R-  (VGA)	ATC index/data read register

(Table P0662)
Values for EGA/VGA indexed registers in ATC:
 00h-0Fh 16 palette registers (see #P0663)
 10h	mode control register (see #P0664)
 11h	(EGA) overscan color register (see #P0665) (default: 00h)
 11h	(VGA) overscan color register (see #P0666) (default: 00h)
 12h	color enable register (see #P0667)
 13h	horizontal pixel panning register
	bit7-4: reserved
	bit3-0: horizontal pixel panning
 14h	(VGA) color select register (default: 00h)
	bit7-4: reserved
	bit3  : s-color 7
	bit2  : s-color 6
	bit1  : s-color 5 (only with 16 pages   16 regs)
	bit0  : s-color 4 (only with 16 pages   16 regs)
 16h	ET3000, ET4000 only: ATC miscellanenous
	(at least on ET4000 'key' protected)
	This register is also supported by ET3000, but the
	  description is proved for ET4000 only.
	bit7  : bypass the internal palette
		(e.g. for HiColor modes with Sierra RAMDACs)
	bit6  : reserved
	bit5-4: select high resolution / color mode
	bit3-0: reserved
SeeAlso: #P0670,#P0700

Bitfields for EGA/VGA indexed ATC palette register:
Bit(s)	Description	(Table P0663)
 7-6	reserved
 5	secondary red video
 4	secondary green/intensity video
 3	secondary blue/mono video
 2	primary red video
 1	primary green video
 0	primary blue video
SeeAlso: #P0662

Bitfields for EGA/VGA ATC mode control register:
Bit(s)	Description	(Table P0664)
 7	(VGA) SB/SG select (0=4 pages of 64 regs, 1=16 pages of 16 regs)
 6	(VGA) PELCLK/2 (0=4bit color, 1=8bit color)
 5	(VGA) enable pixel panning (0=all, 1=up to line compare register value)
 4	reserved
 3	background intensity (0=16 colors, 1=blink)
 2	line graphics enable (0=background, 1=line 8=9)
 1	1=mono, 0=color select
 0	1=graphics, 0=text select
SeeAlso: #P0662

Bitfields for EGA overscan color register:
Bit(s)	Description	(Table P0665)
 7-6	reserved
 5	secondary red (SR)
 4	secondary green (SR) / intensity
 3	secondary blue (SB)
 2	primary red (PR)
 1	primary green (PG)
 0	primary blue (PB)
SeeAlso: #P0662,#P0666

Bitfields for VGA overscan color register:
Bit(s)	Description	(Table P0666)
 7	secondary intensity border color (SI)
 6	secondary red (SR)
 5	secondary green (SG)
 4	secondary blue (SB)
 3	intensity border color (PI)
 2	primary red (PR)
 1	primary green (PG)
 0	primary blue (PB)
SeeAlso: #P0662,#P0665

Bitfields for EGA/VGA color enable register:
Bit(s)	Description	(Table P0667)
 7-6	reserved
 5-4	diagnose / video status select
	EGA:		VGA, ET4000:
	00b = PR/PB	   PR/PB
	01b = SB/PG	   SG/SB
	10b = SR/SG	   PI/PG
	11b = reserved	   SI/SR
 3	enable plane 3
 2	enable plane 2
 1	enable plane 1
 0	enable plane 0
SeeAlso: #P0662
EGA/VGA - MISCELLANEOUS REGISTERS

Code: Alles auswählen

--------V-P03C203CF--------------------------
PORT 03C2-03CF - EGA/VGA - MISCELLANEOUS REGISTERS
Range:	PORT 03C2h or PORT 02C2h (alternate EGA)
SeeAlso: PORT 03C0h,PORT 03C4h,PORT 03C6h,PORT 03D0h

03C2  R-  input status 0 register (see #P0668)
03C2  -W  miscellaneous output register (see #P0669)
03C3  RW  (VGA)	video subsystem enable (see also PORT 46E8h)
		for IBM, motherboard VGA only
			 bit7-4=0: reserved
			 bit3	 : select video subsystem (address 46E8h)
			 bit2-1	 : reserved
			 bit0	 : select video subsystem (address 03C3h)

Bitfields for EGA/VGA input status 0 register:
Bit(s)	Description	(Table P0668)
 7	(VGA) vertical retrace interrupt is pending
	(EGA) =0 vertical retrace in progress
 6-5	(VGA) reserved (0)
 6	(EGA and ET4000) feature control 1 (pin17)
 5	(EGA and ET4000) feature control 0 (pin19)
 4	(VGA) monitor sense signal is asserted
 4	(EGA, Genoa SuperEGA) DIP switch sense
	0=closed, 1=open/switches readable
 3-0	reserved (0)

Bitfields for EGA/VGA miscellaneous output register:
Bit(s)	Description	(Table P0669)
---Genoa SuperEGA in all emulation modes---
 7-6: vertical resolution
	00 (EGA) 200 lines
	01 (VGA) 400 lines
	10 (EGA/VGA) 350 lines
	11 (VGA) 480 lines
------
 7	vertical sync polarity (0=positive, 1=negative)
 6	horizontal sync polarity (0=positive, 1=negative)
 5	odd/even pagebit (=1 select second 64K memory page)
 4	EGA: 0=video driver on,
	     1=video driver off (feature connector used)
 3-2	pixelclock
	00 14/25.175 MHz (EGA/VGA)
	01 16/28.322 Mhz (EGA/VGA)
	10 (EGA/VGA) external clock (EGA)
	10 (Genoa SuperEGA) 39Mhz
	11 (EGA/VGA) reserved
	11 (Genoa SuperEGA) 26.824Mhz
	11 (S3 Trio32/Trio64) enable clock programming via sequencer registers
		  12h and 13h
 1	enable CPU RAM access
 0	CRTC port address
	0=3B4h mono
	1=3D4h color
	   (color EGA: enable feature control at 3DAh,status reg 1 at 3D2h)
EGA/VGA - SEQUENCER REGISTERS

Code: Alles auswählen

----------P03C403C5--------------------------
PORT 03C4-03C5 - EGA/VGA - SEQUENCER REGISTERS
Range:	PORT 03C4h or PORT 02C4h (alternate EGA)
SeeAlso: PORT 03C0h,PORT 03C2h,PORT 03C4h"Cirrus",PORT 03C4h"S3"
SeeAlso: PORT 03C4h"Tseng",PORT 03C6h,PORT 03D0h

03C4  -W  EGA	TS index register
		bit7-3 : reserved (VGA only)
		bit2-0 : current TS index
03C4  RW  VGA	sequencer register index (see #P0670)
03C5  -W  EGA	TS data register
03C5  RW  VGA	sequencer register data

(Table P0670)
Values for EGA/VGA indexed TS (sequencer) registers:
 00h	reset register
	bit7-2 : reserved
	bit1 =0: synchronous reset (EGA/VGA)
	bit0 =0: asynchronous reset (EGA, ET4000)
		 synchronous reset, also (VGA)
 01h	clocking mode register / TS mode (see #P0671)
 02h	map mask register (see #P0672)
 03h	character map select register / font select (see #P0673)
 04h	memory mode register (see #P0674)
 07h	(undoc VGA) reset horizontal character counter
	any write to this register holds horizontal character counter at 00h
	  until any other sequencer register is written
Note:	register 07h is documented in the C&T Wingine documentation
SeeAlso: #P0675,#P0696,#P0685

Bitfields for EGA/VGA sequencer clocking mode register:
Bit(s)	Description	(Table P0671)
 7-6	reserved
 5	(VGA) =1: screen refresh off
 4	(VGA) shift load (0=4x8, 1=1x32)
 3	internal character clock (0=normal, 1=dotclock/2)
 2	serial shift video load (0=4x8, 1=2x16)
 1	(EGA) CRTC bandwidth (0=4/5, 1=2/5)
 0	dot clocks per character (0=9, 1=8) (ET4000: see 06h)
SeeAlso: #P0670

Bitfields for EGA/VGA sequencer map mask register:
Bit(s)	Description	(Table P0672)
 7-4	reserved
 4	Genoa SuperEGA only: plane4 ???
 3	write enable display memory plane 3
 2	write enable display memory plane 2
 1	write enable display memory plane 1
 0	write enable display memory plane 0
SeeAlso: #P0670

Bitfields for EGA/VGA sequencer character map select register:
Bit(s)	Description	(Table P0673)
 7-6	reserved
 5	(VGA) bit3 for second text-font
 4	(VGA) bit3 for first text-font
 3-2	second text-font (attr bit3=1)
 1-0	first text-font (attr bit3=0)
	offset in font memory (4-7: VGA only)
	   0 00b =  0KB
	   0 01b = 16KB
	   0 10b = 32KB
	   0 11b = 48KB
	   1 00b =  8KB
	   1 01b = 24KB
	   1 10b = 40KB
	   1 11b = 56KB
SeeAlso: #P0670

Bitfields for EGA/VGA sequencer memory mode register:
Bit(s)	Description	(Table P0674)
 7-4	reserved
 3	=1 (VGA) enable chain 4 linear graphics mode
	(when set, low two bits of CPU address select the plane)
 2	addressing mode
	0 odd/even mode (even addresses access planes 0/2, odd planes 1/3)
	1 sequential mode
 1	=1 extended memory (0=64KB, 1=more)
 0	(EGA) 1=textmode, 0=graphics mode
SeeAlso: #P0670
EGA/VGA/MCGA - DAC REGISTERS

Code: Alles auswählen

--------V-P03C603C9--------------------------
PORT 03C6-03C9 - EGA/VGA/MCGA - DAC REGISTERS
Range:	PORT 03C6h or PORT 02C6h (alternate)
SeeAlso: PORT 03C0h,PORT 03C2h,PORT 03C4h,PORT 03CAh,PORT 03CEh"EGA",PORT 03D0h
SeeAlso: PORT 83C6h"Wingine"

03C6  RW  (VGA, MCGA) PEL mask register (default FFh)
		 VGA:	AND mask for color-register address.
		 MCGA:	Never change from the default FFh.
03C6  RW  HiColor ET4000 (Sierra RAMDACs e.g. SC11486, SC11481, SC11488):
		 Enable HiColor feature: beside other assignments,
		 consequtive read 3C6h 4 times and write magic value 80h to it.
03C7  -W  (VGA,MCGA,CEG-VGA) PEL address register (read mode)
		 Sets DAC in read mode and assign start of color register
		 index (0..255) for following read accesses to 3C9h.
		 Don't write to 3C9h while in read mode. Next access to
		 03C8h will stop pending mode immediatly.
03C7  -W  (CEG-Color VGA w/ Edsun Labs RAMDACs)
		 Enable and set Countinous Edge Graphics Mode:
		 Consecutive writely the following three key sequences in read
		 mode (!) to 3C9h register DEh : 'CEG', 'EDS', 'UNx' (x see
		 below). Current CEG mode can be read from palette register
		 BFh 'blue', write access to that register will disable CEG
		 features.
		 In CEG modes by combining old with new colors and dynamically
		 changing palette values, the effective colors displayable
		 are enhanced dramatically (in EDP modes up to virtually 32bit
		 truecolor) on standard 16/256 color VGA. Also, effective
		 resolution enhancement takes effect by anti-aliasing.
		 Necessary EDP escape sequences should be moved to image
		 border or single colored areas, if possible.

		 REP-mode: if pixel are doubled in current video mode
		 EDP-mode: pseudo-truecolor with Edsun dynamic palette
		 (see #P0698,#P0699)

		 Palette-color-register single-byte-format (each 3 times):
		  Mode A:		  Mode C:
		   bit7-4: mix code	   bit3	 : 0=color, 1=code
		   bit3-0: color code	   bit2-0: color / mix code
		  Mode B:		  Mode D:
		   bit7-5: mix code	   bit7-0: see mix code table
		   bit4	 : 0=new, 1=old	  Non-CEG modes:
		   bit3-0: color code	   bit7-0: as usual

		 In EDP modes, video-memory-palette-changing escape-sequences:
		  Mode A:     Mode B:	  Mode C:     Mode D:
		   7/escape    7/escape	   7/escape    0BFh
		   red	       red	   red7-4      red
		   green       green	   red3-0      green
		   blue	       blue	   green7-4    blue
		   address     address	   green3-0    address
					   blue7-4
					   blue3-0
					   address
03C7  R-  VGA	DAC state register
		bit7-2 reserved
		bit1-0: 00b write palette cycle (write mode)
			01h reserved
			10b reserved
			11b read palette cycle (read mode)
03C8  RW  (VGA,MCGA) PEL address register (write mode)
		 Sets DAC in write mode and assign start of color register
		 index (0..255) for following write accesses to 3C9h.
		 Don't read from 3C9h while in write mode. Next access to
		 03C8h will stop pending mode immediatly.
03C8  RW  (Genoa SuperEGA) SuperEGA control register (all emulation modes)
		  bit7-2: reserved
		  bit1	: 0=EGA mode, 1=backward compatibility mode
		  bit0	: not used
03C8  R?  (S3 Trio32/64) General Input Port (see #P0738)
03C9  RW  (VGA,MCGA) PEL data register
		 Three consequtive reads (in read mode) or writes (in write
		 mode) in the order: red, green, blue. The internal DAC index
		 is incremented each 3rd access.
		  bit7-6: HiColor VGA DACs only: color-value bit7-6
		  bit5-0:			 color-value bit5-0

(Table P0698)
Values for EDSUN CEG (Continuous Edge Graphics) modes::
 x:  mode:	 colors:  mix:	pixel depth:  effective colors:
 0 = disabled	   256	   -	     8		    256
 1 = A		    16	  16	     8		   1920
 2 = A+REP	    16	  16	  8 dblscn	   1920
 3 = A+EDP	    15	  16			truecolor
 4 = reserved	     -	   -	     -		     -
 5 = B		    16	   8	     8		    960
 6 = B+REP	    16	   8	  8 dblscn	    960
 7 = B+EDP	    15	   8			truecolor
 8 = reserved	     -	   -	     -		     -
 9 = C		     8	   8	     4		    224
 10 = C+REP	     8	   8	  4 dblscn	    224
 11 = C+EDP	     7	   8			truecolor
 12 = reserved	     -	   -	     -		     -
 13 = D		   223	  32	     8		 792096
 14 = D+REP	   223	  32	  8 dblscn	 792096
 15 = D+EDP	   223	  32			truecolor
SeeAlso: #P0699

(Table P0699)
Values for EDSUN CEG mixing codes:
 Mode A:	       |  Mode C:
 mix: new:	old:   |   mix: new:   old:   colorcode:
   0 = 32/32	0/32   |    0 =	  -	 -     0
   1 = 30/32	2/32   |    1 =	  -	 -     1
   2 = 28/32	4/32   |    2 =	  -	 -     2
   3 = 26/32	6/32   |    3 =	  -	 -     3
   4 = 24/32	8/32   |    4 =	  -	 -     4
   5 = 22/32   10/32   |    5 =	  -	 -     5
   6 = 20/32   12/32   |    6 =	  -	 -     6
   7 = 18/32   14/32   |    7 =	  -	 -     7/EDP
   8 = 16/32   16/32   |    8 = 30/32	2/32   -
   9 = 14/32   18/32   |    9 = 28/32	4/32   -
  10 = 12/32   20/32   |   10 = 26/32	6/32   -
  11 = 10/32   22/32   |   11 = 24/32	8/32   -
  12 =	8/32   24/32   |   12 = 22/32  10/32   -
  13 =	6/32   26/32   |   13 = 20/32  12/32   -
  14 =	4/32   28/32   |   14 = 18/32  14/32   -
  15 =	2/32   30/32   |   15 = 16/32  16/32   -
---Mode B:	       |  Mode D:
 mix: new:	old:   |   mix:	      new:   old:  description:
   0 = 30/32	2/32   |   00h..BEh =	-      -   normal color
   1 = 26/32	6/32   |   BFh	    =	-      -   EDP
   2 = 22/32   10/32   |   C0h	    = 32/32   0/32
   3 = 18/32   14/32   |   C1h	    = 31/32   1/32
   4 = 14/32   18/32   |   C2h	    = 30/32   2/32
   5 = 10/32   22/32   |   ...	    =  ...    ...
   6 =	6/32   26/32   |   DFh	    =  0/32  32/32
   7 =	2/32   30/32   |   E0h-FFh  =	-      -   normal color
SeeAlso: #P0698
EGA/VGA/MCGA - GRAPHICS CONTROLLER REGISTERS

Code: Alles auswählen

--------V-P03CE03CF--------------------------
PORT 03CE-03CF - EGA/VGA/MCGA - GRAPHICS CONTROLLER REGISTERS
Range:	PORT 03CEh or PORT 02CEh (alternate EGA)
SeeAlso: PORT 03C0h,PORT 03C2h,PORT 03C4h,PORT 03C6h,PORT 03D0h
SeeAlso: PORT 03CEh"Chips&Technologies"

03CE  -W  EGA	GDC index register
03CE  RW  VGA	graphics address register / GDC index
		      bit7-4: reserved
		      bit3-0: index
03CF  -W  EGA	GDC data register (see #P0700)
03CF  RW  VGA	other graphics register (see #P0700)

(Table P0700)
Values for EGA/VGA indexed registers in GDC:
 00h	set/reset register (default 00h)
	functionality depending on write mode (register 05h) (see #P0704)
	bit7-4: reserved
	bit3  : 0=write 00h, 1=write FFh in plane 3
	bit2  : 0=write 00h, 1=write FFh in plane 2
	bit1  : 0=write 00h, 1=write FFh in plane 1
	bit0  : 0=write 00h, 1=write FFh in plane 0
 01h	enable set/reset register (default 00h) (see #P0701)
 02h	color compare register (default 00h) (see #P0702)
 03h	data rotate register (default 00h) (see #P0703)
 04h	read map select register (default 00h)
	bit7-3: reserved
	bit2  : EGA?? & Genoa SuperEGA: map select bit2
	bit1-0: map select (0..3)
 05h	mode register (see #P0704)
 06h	miscellaneous register (see #P0705)
 07h	color don't care register
	bit7-4: reserved
	bit3=1: color plane 3 don't care (ignore bit3)
	bit2=1: color plane 2 don't care (ignore bit2)
	bit1=1: color plane 1 don't care (ignore bit1)
	bit0=1: color plane 0 don't care (ignore bit0)
 08h	bit mask register (default FFh)
	bit7-0: bitmask for latch/databyte
	      (bit set=change allowed)
---Paradise SuperVGA---
 0Fh	lock register
	The ability to write and reread 00h..07h to this register
	is often used as detection of Paradise chips.
	bit7-0 = 01h lock/hide Paradise specific registers
	       = 05h unlock Paradise specific registers
	bit7-3: reserved
	bit2-0: flipflops, reserved
SeeAlso: #P0706

Bitfields for EGA/VGA GDC enable set/reset register:
Bit(s)	Description	(Table P0701)
 7-4	reserved (used on Genoa SuperEGA???)
 3	enable set/reset plane 3
 2	enable set/reset plane 2
 1	enable set/reset plane 1
 0	enable set/reset plane 0
 3-0	0=CPU access, 1=set/reset access to plane
SeeAlso: #P0700

Bitfields for EGA/VGA GDC color compare register:
Bit(s)	Description	(Table P0702)
 7-4	reserved
 3	color compare 3
 2	color compare 2
 1	color compare 1
 0	color compare 0
 3-0	(color number)
SeeAlso: #P0700

Bitfields for EGA/VGA data rotate register (GR3):
Bit(s)	Description	(Table P0703)
 7-5	reserved
 4-3	logical function select
	00 CPU-data overwrites
	01 CPU-data AND with latch-register
	10 CPU-data OR with latch-register
	11 CPU-data XOR with latch-register
 2-0	rotate count
SeeAlso: #P0700

Bitfields for EGA/VGA GDC mode register:
Bit(s)	Description	(Table P0704)
 7	reserved
 6	(VGA) 0=standard, 1=enable 256 colors
 5	shift register mode, 0=standard, 1=CGA-graphics
	  (not used on Genoa SuperEGA???)
 4=1	enable odd/even address mode
 3	read mode, 0=mode0, 1=mode1
 2	(EGA) test condition, 0=standard, 1=output tristate
 1-0	write mode
	00 mode0, plane source is CPU or set/reset
	01 mode1, plane source is latch-register
	10 mode2, plane source is CPU as set/reset
	11 (VGA) mode3, CPU as set/reset AND bitmask
SeeAlso: #P0700

Bitfields for EGA/VGA GDC miscellaneous register:
Bit(s)	Description	(Table P0705)
 7-4	reserved (=0)
 3-2	memory map
	00b = A0000..BFFFF (128KB)
	01b = A0000..AFFFF (64KB)
	10b = B0000..B7FFF (32KB)
	11b = B8000..BFFFF (32KB)
 1	chain odd maps to even, 1=subst addess bit0
 0	0=textmode, 1=graphics mode
SeeAlso: #P0700
COLOR VIDEO - CRT CONTROL REGISTERS

Code: Alles auswählen

--------V-P03D403D5--------------------------
PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS

03D4  rW  CRT (6845) register index   (CGA/MCGA/color EGA/color VGA)
	selects which register (0-11h) is to be accessed through 03D5
	this port is r/w on some VGA, e.g. ET4000
	    bit 7-6 =0: (VGA) reserved
	    bit 5   =0: (VGA) reserved for testage
	    bit 4-0   : selects which register is to be accessed through 03D5
03D5  -W  CRT (6845) data register   (CGA/MCGA/color EGA/color VGA) (see #P0708)
	selected by PORT 03D4h. registers 0C-0F may be read
	  (see also PORT 03B5h)
	MCGA, native EGA and VGA use very different defaults from those
	  mentioned for the other adapters; for additional notes and
	  registers 00h-0Fh and EGA/VGA registers 10h-18h and ET4000
	  registers 32h-37h see PORT 03B5h (see #P0654)
	registers 10h-11h on CGA, EGA, VGA and 12h-14h on EGA, VGA are
	  conflictive with MCGA (see #P0710)

(Table P0708)
Values for EGA/VGA+ CRT Controller register index:
 00h-0Fh	same as MDA/CGA (see #P0654)
 10h R-	native VGA with bit7=1 in end horizontal blanking (03h) and ET4000:
	       start vertical retrace
 10h -W start vertical retrace
 11h R- native VGA with bit7=1 in end horizontal blanking (03h):
	       end vertical retrace
 11h -W end vertical retrace
	       bit7  : VGA: protection bit
			    =0 enable write access to 00h-07h
			    =1 read only regs 00h-07h with the exception
			       of bit4 in 07h. ET4000: protect 35h also.
	       bit6  : VGA: =0 three, =1 five refreshcycles/line
		       ET4000: reserved
	       bit5=0: (MCGA also) enable vertical interrupt
	       bit4=0: (MCGA also) clear vertical interrupt
		   =1:		   no effect
	       bit3-0: (MCGA also) vertical retrace end
 12h	vertical display end register
 13h	row offset register
	       logical screen line width in
		byte mode : bytes/(line/2)
		word mode : bytes/(line/4)
		dword mode: bytes/(line/8)
 14h	underline location register
	       bit7: reserved (0)
	       bit6: (VGA) 0=word-mode, 1=dword-mode (see 17h, bit6)
	       bit5: (VGA) 0=standard address counter clock
			   1=address counter clock/4 (see 17h, bit3)
	       bit4-0: horizontal underline row scan
 15h	(EGA,VGA) start vertical blanking-1
 16h	(EGA,VGA) end vertical blanking register
	       bit7-5 : EGA: reserved, but used on original EGA???
	       bit4-0 : end vertical blanking
 17h	(EGA,VGA) "CR17" mode control register (see #P0657)
 18h	(EGA,VGA) "CR18" line compare register
 19h	Genoa SuperEGA only: double scan control
	       at 3B5h only in MDA, HGC emulation, but at 3D5h even in
	       mono EGA modes.
	       bit7-5 : reserved
	       bit4   : HR/VR width adjust flag for double scan mode
	       bit3-1 : 1=test, 0=normal
	       bit0   : double scan enable
 1Dh	Elsa Victory Erazor only: video page select for writing
		bits 7-1 = offset into video memory in 64K units
		bit 0: ???
 1Eh	Elsa Victory Erazor only: video page select for reading
		bits 7-1 = offset into video memory in 64K units
		bit 0: ???
 22h	(VGA) "CR22" CPU Latch Data Register (read-only)
 24h	(VGA) "CR24" Attribute Controller Toggle register (R-O) (see #P0709)
 3xh	(VGA)  !!!chips\64200.pdf p.57
Notes:	registers 10h-14h on the MCGA have conflicting uses (see #P0710)
	registers 22h,24h, and 3xh exist on the standard IBM VGA but were not
	  documented
SeeAlso: #P0756,#P0716,#P0717

Bitfields for VGA "CR24" Attribute Controller Toggle register:
Bit(s)	Description	(Table P0709)
 7-3	current attribute controller index
 2	palette address source
 1	reserved
 0	state of attribute-controller flip-flop (0 = index, 1 = data)
Note:	this register was not documented for the original IBM VGA; this
	   description is from the C&T Wingine documentation
SeeAlso: #P0708,#P0718

(Table P0710)
Values for MCGA (only) CRT Controller register index:
 00h-0Fh	same as MDA/CGA (see #P0654)
 10h -W mode control register (defaults 18h, 1Ah, 19h) (see #P0711)
 10h R-	mode control status register (see #P0712)
 11h -W	interrupt control register (default 30h) (see #P0713)
 12h RW	character generator/sync polarity register (see #P0714)
 12h R-	display sense register (int. control reg [11h] bit7=1)
	bit 7-2	 : not used
	bit 1-0	 : pins 11 & 12 in monitor cable
		00b = reserved
		01b = analogue monochrom monitor
		10b = analogue color graphics monitor
		11b = no monitor
 13h -W character font pointer register (see #P0710)
	only 00h, 10h, 20h, 30h (default 00h) are allowed here
	  for textmode fonts at A0000, A2000, A4000, A6000
 14h -W	number of characters to load during vert. retrace period (default FFh)
Note:	registers 10h-14h can appear at PORT 03D5h only, not at 03B5h
SeeAlso: #P0654,#P0708,#P0756,#P0715

Bitfields for MCGA (only) CRT mode control register:
Bit(s)	Description	(Table P0711)
 7	suppress hsync/vsync
 6	reserved (0)
 5	reserved
 4	dot clock rate
 3	refresh calculations in 80x25 modes
 2	reserved
 1	videomode 11h active
 0	videomode 13h active
SeeAlso: #P0710,#P0712

Bitfields for MCGA (only) CRT mode control status register:
Bit(s)	Description	(Table P0712)
 7	status bit0 CGA mode control register
 6	reserved
 5	clockrate 640 pixel, =0: clockrate/2 320 pixel
 4	clock rate is 25,175Mhz
 3	currently in textmode
 2	double-scan activated
 1	videomode 11h active
 0	videomode 13h active
SeeAlso: #P0710,#P0711

Bitfields for MCGA (only) CRT interrupt control register:
Bit(s)	Description	(Table P0713)
 7	set output driver to tristate
	=0: for reading of character generator reg (12h)
	=1: for reading of display sense register (12h)
 6   R	intr generated by memory controller
 5	=0 requested intr ok to handle
 4	=0 free interrupt latch register
 3-0	reserved
SeeAlso: #P0710

Bitfields for MCGA (only) CRT character generator/sync polarity register:
Bit(s)	Description	(Table P0714)
 7	character generator active
 6	=1 load codepage during display
	=0 load codepage during retrace
 5	codepage number (0,1)
 4	512 characters active
 3	reserved (0)
 2	enable hsync/vsync
 1	positive vsync polarity
 0	positive hsync polarity
Note:	default 46h in all modes, except 04h in mode 11h)
SeeAlso: #P0710
COLOR VIDEO - CRT MODE AND STATUS REGISTERS

Code: Alles auswählen

----------P03D803DF--------------------------
PORT 03D8-03DF - COLOR VIDEO - CRT MODE AND STATUS REGISTERS

03D8  RW  CGA mode control register  (except PCjr) (see #P0817)
	cannot be found on native color EGA, color VGA, but on most clones
03D9  RW  CGA palette register (see #P0819)
	(MCGA) CGA border control register
	Cannot be found on native EGA, VGA (without translation ROM) but
	  only most clones. Read access on Genoa SuperEGA is 'reset'???
03DA  R-  CGA status register (see #P0818)
	color EGA/VGA: input status 1 register
03DA  -W  color EGA/color VGA feature control register (see #P0820)
	(at PORT 03BAh w in mono mode, VGA: 3CAh r)
03DA  -W  HZ309 (MDA/HGC/CGA clone) card from in Heath/Zenith HZ150 PC
	bit7-1=0: unknown, zero is default and known to function
		   properly at least in CGA modes.
	bit 0 = 1 override 3x8h bit3 control register that switches
		   CRT beam off if bit3 is cleared. So screens always
		   stays on.
	bit 0 = 0 3x8h bit3 indicates if CRT beam is on or off.
		   No more info available. Might conflict with EGA/VGA.
03DB  rW  clear light pen latch	(not MCGA)
		  (R/W only with Genoa SuperEGA)
03DC  RW  (not MCGA) preset light pen latch
03DC  -W  (CGA) set light pen latch
03DD  -W  (MCGA)  Extended mode control register
	  (Plantronics & Genoa SuperEGA: Plantronics ColorPlus control,
		      compatible with MCGA???)
	(default is 00h, in mode 13h: 04h)
	bit7 =1: DAC active, cannot be read
	     =0: DAC not active, read allowed
	bit6-5 : reserved
	bit4   : AST_PLANTRONICS
	bit3   : reserved
	bit2 =1: videomode 13h with 256 colors active
	bit1	: reserved
	bit0 =0: reserved
     	Note:	Apparently on the AST "ColorGraphPlus", its Enhanced mode can
		  be activated with 90h and reset with 00h; on this card the
		  Plantronics mode can be enabled with 10h.
03DE  --  (MCGA) reserved
03DE  -W  (AT&T & color ET4000 in AT&T compatibility mode & C&T 82C426)
	  AT&T mode control register (see #P0821)
	(register enabled in ET4000, if bit7=1 in CRTC 3D4h/34h.)
03DF  --  (MCGA) reserved
03DF  ?W  CRT/CPU page register	 (PCjr only)

Bitfields for CGA/Hercules mode control register:
Bit(s)	Description	(Table P0817)
 7-0	=A0h color ET4000: second part of 'key', see Hercules compatibility
	  register (see PORT 03BFh) for details. For resetting the key, e.g.
	  write 01h to PORT 03BFh and 29h to PORT 03D8h.
 7	(Hercules) page select
	=0 B0000h
	=1 B8000h
 6	color ET4000 only, read-only: report status of bit 1 (enable 2nd page)
	  of hercules compatibility register (see PORT 03BFh)
 5	=1  blink enabled instead of foreground high-int.
 4	=1  640*200 graphics mode (CGA)
 3	=1  video enabled (HZ309, see PORT 03DAh bit 0)
 2	=1  monochrome signal
		(MCGA) in mode 6 and 11h color comes from palette
		  regs 00 (black) and 07 (white), and can be changed there.
 1	=0  text mode
	=1  320*200 graphics mode
 0	text columns (0 = 40*25 text mode, 1 = 80*25 text mode)
SeeAlso: #P0818

Bitfields for CGA status register:
Bit(s)	Description	(Table P0818)
 7-6	not used
 7	(C&T Wingine) vertical sync in progress (if enabled by XR14)
 5-4	color EGA, color ET4000, C&T: diagnose video display feedback, select
	  from color plane enable
 3	in vertical retrace
	(C&T Wingine) video active (retrace/video selected by XR14)
 2	(CGA,color EGA) light pen switch is off
	(MCGA,color ET4000) reserved (0)
	(VGA) reserved (1)
 1	(CGA,color EGA) positive edge from light pen has set trigger
	(VGA,MCGA,color ET4000) reserved (0)
 0	horizontal retrace in progress
	=0  do not use memory
	=1  memory access without interfering with display
	    (VGA,Genoa SuperEGA) horizontal or vertical retrace
	(C&T Wingine) display enabled (retrace/DE selected by XR14)
SeeAlso: #P0817,#P0819,#P0762

Bitfields for CGA palette register:
Bit(s)	Description	(Table P0819)
 7-6	not used
 5	=0 active 320x200x4 color set: red, green brown
	=1 active 320x200x4 color set: cyan, magenta, white
 4	intense colors in graphics, background colors text
 3	intense border in 40*25, intense background in 320*200, intense
	  foreground in 640*200
 2	red border in 40*25, red background in 320*200,	red foreground in
	  640*200
 1	green border in 40*25, green background in 320*200, green foreground
	  in 640*200
 0	blue border in 40*25, blue background in 320*200, blue foreground in
	   640*200
SeeAlso: #P0817,#P0818

Bitfields for color EGA/VGA feature control register:
Bit(s)	Description	(Table P0820)
 7	ET4000 only: enable NMI generation ('key' protected)
 6-4	not used
 3	(VGA) 0 = normal vsync, 1 = vsync OR display enable
 2	reserved (0)
	(C&T Wingine) disable 16-bit operations
 1	(EGA,ET4000,Wingine) FEAT1 control bit1 (pin17 feature connector)
	(VGA) reserved (0)
 0	(EGA,ET4000,Wingine) FEAT0 control bit0 (pin19 feature connector)
	(VGA) reserved (0)
SeeAlso: #P0818

Bitfields for AT&T mode control register:
Bit(s)	Description	(Table P0821)
 7	reserved
 6	underline color attribute enable
	ET4000: enabled, if bit6=1 in CRTC 3D4h/34h.
 5	reserved
 4	reserved
 3	alternate page select (=1: 2nd 16KB page, with bit0=0)
 2	alternate font select (0=default font block)
 1	reserved
 0	double scan line mode (0=IBM 200, 1=AT&T 400 line graphics)
	(ET4000) enabled, if bit7-6=11b in CRTC 3D4h/34h.
http://www.sterotronic.com/projekte/low ... afikkarten

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: TUI programmieren [C]

Beitrag von freecrac »

oDOSseus hat geschrieben:Ne mich interessierte z.B. wo diese Font liegt. Sowas wird nirgens erklärt.
RBIL->inter61b.zip->INTERRUP.E

Code: Alles auswählen

--------B-1F---------------------------------
INT 1F - SYSTEM DATA - 8x8 GRAPHICS FONT
Desc:	this vector points at 1024 bytes of graphics data, 8 bytes for each
	  character 80h-FFh
Notes:	graphics data for characters 00h-7Fh stored at F000h:FA6Eh in 100%
	  compatible BIOSes
	Under PhysTechSoft's PTS ROM-DOS this table is fictitious.
SeeAlso: INT 10/AX=5000h,INT 43
Dieser Vector befindet sich an der Adresse 1Fh*4(= 0:007Ch) und dort findet man die Adresse(Offset, Segment ) des 8x8-Fonts.
Bei mir steht dort: 50 C8 00 C0 ergibt die Adresse => C000:C850.

RBIL->inter61c.zip->INTERRUP.N

Code: Alles auswählen

--------V-43---------------------------------
INT 43 - VIDEO DATA - CHARACTER TABLE (EGA,MCGA,VGA)
Desc:	points at graphics data for characters 00h-7Fh of the current font
	  in 8x8 dot modes, graphics data for all characters in 8x14 and 8x16
	  modes
Note:	this is not a callable vector!
SeeAlso: INT 06"no-name",INT 1F"SYSTEM DATA",INT 44"VIDEO"

Code: Alles auswählen

--------V-44---------------------------------
INT 44 - VIDEO DATA - ROM BIOS CHARACTER FONT, CHARACTERS 00h-7Fh (PCjr)
Desc:	this vector points at graphics data for current character font
SeeAlso: INT 1F"SYSTEM DATA",INT 43"VIDEO"
Dirk
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: TUI programmieren [C]

Beitrag von DOSferatu »

oDOSseus hat geschrieben:Ich habe deinen Code jetzt mal so abgetippt, aber es wird nur jede zweite zeile übernommen. Der Rest bleibt vom Originalbuchstaben.
also 1Zeile mein buchstabe,1Zeile standard,1Zeile mein Buchstabe,1Zeile standard usw.
Vielleicht aus Versehen statt
REPNZ MOVSB

REPNZ MOVSW
geschrieben?
Außerdem hätte ich natürlich nicht "Adresse des Zeichensatzes", sondern "Adresse des Zeichens" für DS:SI schreiben sollen.
Gibt man die Adresse des ZeichenSATZES in DS:SI an, muß natürlich noch eine kleine Berechnung vorgenommen werden, und zwar SI um CX*DI erhöht werden (nämlich, damit man die Adresse des Zeichens innerhalb des Zeichensatzes bekommt, das man setzen will - unter der Voraussetzung, daß der Zeichensatz lückenlos die Zeichen hintereinander gespeichert hat.
Hier der geänderte Code dafür:

CX =Zeilenanzahl des Zeichens
DS:SI = Adresse des Zeichensatzes
DI = Nummer des Zeichens

Code: Alles auswählen

{Setzt neues Zeichen}
@SetChar:
  pushA         {Alle Register retten}
  push ES       {ES auch retten}
  and DI,$00FF  {Highbyte von DI loeschen - zur Sicherheit...}
  mov AX,DI     {## Für Multiplikation vorbereiten}
  mul CX        {## Offset des Zeichens innerhalb des zu setzenden Zeichensatzes}
  add SI,AX     {## Und den Offset addieren}
  shl DI,5      {32 Zeilen pro Zeichen}
  mov AX,$A000  {Segment=$A000}
  mov ES,AX     {Nach ES}
  pushF         {Flags retten (weil Direction-Flag und Int-Flag geandert}
  cld           {Direction Flag auf "vorwaerts"}
  cli           {Interrupts sperren}
  mov DX,$03C4  {Port $03C4 der VGA}
  mov AX,$0402  {VGA-Register $02, Wert $04}
  out DX,AX     {...setzen}
  mov AX,$0704  {VGA-Register $04, Wert $07}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  mov AH,$02    {VGA-Register $04 (AL unverändert), Wert $02}
  out DX,AX     {...setzen}
  mov AX,$0005  {VGA-Register $05, Wert $00}
  out DX,AX     {...setzen}
  inc AL        {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  repnz movsb   {CX bytes von DS:SI nach ES:DI kopieren}
  mov DL,$C4    {Port $03C4 der VGA}
  mov AX,$0302  {VGA-Register $02, Wert $03}
  out DX,AX     {...setzen}
  mov AL,$04    {VGA-Register $04, Wert $03}
  out DX,AX     {...setzen}
  mov DL,$CE    {Port $03CE der VGA}
  xor AH,AH     {VGA-Register $04, Wert $00}
  out DX,AX     {...setzen}
  mov AX,$1005  {VGA-Register $05, Wert $01}
  out DX,AX     {...setzen}
  mov AX,$0E06  {VGA-Register $06, Wert $0E}
  out DX,AX     {...setzen}
  popF          {Flags zurueckholen auf vorige Werte}
  pop ES        {ES zurueckholen}
  popA          {Alle Register zurueckholen}
  ret           {Ruecksprung aus der Subroutine}
Die drei neuen Zeilen habe ich mit ## markiert. Außerdem, wie gesagt, bitte die REPNZ MOVSB Zeile beachten.

Achja, zur Frage nochmal, wegen der "Lücke":
Ich meinte, ich hätte das erklärt. Die Grafikkarte erlaubt Zeichen mit einer Höhe von maximal 32 Zeilen - entsprechend 32 Bytes. Um die Verarbeitung zu vereinfachen, sind die Anfänge der Zeichen IMMER an den Zeichennummer*32 Offsets - egal, welche Linienanzahl für die Darstellung eingestellt ist. Prinzipiell läuft das so ab, daß die Grafikkarte zu Anfang intern ein Register auf 0 setzt, eine Zeile lang die Bytes aller Zeichen liest und darstellt, eben ZeichenNr*32+Zeile (bzw SHL 5), dann das Register um 1 erhöht, dann die nächste Zeile... Und wenn das Register irgendwann die eingestellte Zeilenzahl der ZEICHEN enthält, wird das Register wieder auf 0 gesetzt. (Das ist sehr einfach formuliert. In Wirklichkeit liegen die 5 Bits des "Registers" und die Bits für die Zeichennummer intern sicher direkt "übereinander", so daß sie die direkte Zeichenadresse ergeben...)
Das bedeutet: Alleine durch ändern der Zeilenzahl für die Zeichen ändert man automatisch die Zeilenzahl der Textzeilen auf dem Bildschirm, bei gleicher Bildauflösung. Es muß dann eben nur ein neuer Zeichensatz geladen werden, der in diese weniger oder mehr Zeichenzilen paßt - sonst siehts eben komisch aus. (Beispiel: Wenn Mode 80x25 Zeichen geladen und man halbiert die Zeichenzeilenzahl, hat man den 80x50 Zeichen Mode, allerdings mit halben Zeichen des 80x25 Zeichensatzes (obere Hälfte). Zusätzlich muß nun noch ein passender 8x8 Pixel Zeichensatz für den 80x50 Mode geladen werden.)
Die Funktionen
INT $10, AX=$1112, BL=$00 (80x50 Mode mit Zeichensatz)
und
INT $10, AX=$1114, BL=$00 (80x25 Mode mit Zeichensatz)
setzen übrigens die entsprechenden Modi und laden den Zeichensatz.

Ich wollte hier noch einige andere Dinge anmerken, zu persönlichen Spielereien. Aber das wäre schon teilweise sehr Off-Topic gewesen, daher habe ich es wieder gelöscht.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: TUI programmieren [C]

Beitrag von oDOSseus »

ich habe natürlich die stosb methode benutzt.
Ich glaube eher, ich habe mich iwo vertippt. Aber wie gesagt: mit dem source-code von dem link klappts. Das ist ja erstmal das, was ich wollte. Und da er hier auch steht sollte es für spätere thread-leser kein Problem sein, das nachzuvollziehen.

Ich fand jedoch, dass du deinen sourcecode nicht so gut kommentiert hast. Das soll jetzt nicht undankbar klingen, denn ich finds echt super, dass du mir das gezeigt hast, aber nur eine Erklären DAS du etwas an einen Port sendest ist eher irrelevant und ich würde eine Erklärung WARUM man was an einen Port sendet vorziehen. aber die is ja jetzt von freecrac gekommen.

Alles in allem: Es funktioniert und ich habe nun ein breites Grinsen im Gesicht.
Antworten