

Bildschirmbearbeitung
---------------------

Ich habe heute (diese Ausgabe hehe) einfach mal als Grund 
genommen, um mal 'n bisschen ber Bilschirmausgaben zu labern.
Nchste Ausgabe schreib ich vielleicht was ber Tastaturen +so.

Die Ausgaben auf dem Bildschirm sind (abgesehen von einem Virus)
Hauptbestandteil eines Programms. Ich will hierbei mehr auf die
Ansteuerung der Textmodi in Assembler eingehen.
Die Ansteuerung lsst sich unterteilen in:
 -Interrupts(IRQ)
 -Port's   sowie
 -Segmente

Interrupts
***********

Es gibt genau 4 IRQ's(+21h) in denen man was mit dem Bildschirm 
machen kann:

IRQ.No   |  Funktion
=========|======================================================
10h      | Allgemeine Routinen
1Dh      | Video-Tabelle
1Fh      | Zeichen-Matrix
29h      | Zeichen ausgeben
----------------------------------------------------------------

Wie viele bis einige wissen, gibt es fr die Textansteuerung
einen IRQ 10h.
Dabei gibt es auch viele Unterfunktionen, deren Nummer(n) im
Register AH gespeichert werden muss.
Zu beachten  ist dabei aber, dass man ber's BIOS geht, und
das lsst sich Zzzzeeeeiiiitttt (Zeit).

Ah= |    Funktion    |     Eingabe         |     Ausgabe
====|================|=====================|====================
00h | Modus setzen   |AL   :ModusNummer    |     . /
    |                |                     |      / .
----|----------------|---------------------|--------------------
0Fh |  Modus         |     . /             |AL:Modusnummer
    |  ermitteln     |      / .            |
----|----------------|---------------------|--------------------
01h | Cursorform     |CH:Startzeile        |     . /
    |  setzen        |CL:Endzeile          |      / .
----|----------------|---------------------|--------------------
02h | Cursorposition |DH:Zeile;DL:Spalte   |     . /
    |   setzen       |BH:Seite             |      / .
----|----------------|---------------------|--------------------
03h |cursorform+pos. |BH:Seite             |DH:Zeile;DL:Spalte
    |   ermitteln    |                     |CH+CL siehe F.01h
----|----------------|---------------------|--------------------
05h |  Seite whlen  |AL:Seite             |     . /
    |                |                     |      / .
----|----------------|---------------------|--------------------
09h |Zeichen und Attr|AL:zeichen           |     . /
    |an Cursorpositio|CX:anzahl;BH:Seite   |      /
    | setzen         |BL:Attribut          |     / . 
----|----------------|---------------------|--------------------
0Ah |Zeichen an      |AL:Zeichen           |     . /
    |Cursorpos. setze|CX:Anzahl;BH:Seite   |      / .
----|----------------|---------------------|--------------------
0Bh |Rahmenfarbe und |BH=0 \  BL:Farbe     |     . /
    |Palette setzen  |BH=1 /  BL:Palette   |      / .
================================================================

AL MUSS hierbei mit 00h geladen sein, da wenn es z.B. mit 4Fh
geladen ist, z.B. VESA-Funktionen angesprochen werden!
(AUSSER: AL wird in EINGABE verwendet)

Ein  kleines Bsp, wie man das in Asm benutzt:
Ab  Position 1,1 200 mal  'A' ausgeben

{start}
   mov  ax,0005h ;Seite 00 + Funktion 05h ->AX     \Ausgaben 
   int  10h      ;Interrupt 10h aufrufen           /auf Seite 0
   mov  ax,0002h ;Funktion 02h -> AH(0002h ->AX)   \Pos 1,1
   mov  dx,0101h ;Position 01,01 -> DX             |Seite 0
   mov  bh,00h   ;Seite 00 -> BH                   |setzen
   int  10h      ;Interrupt 10h aufrufen           /
   mov  ax,410Ah ;Char 41h(='A')+Funktion 0Ah->AX  \200mal
   mov  cx,0128h ;128 mal ->CX                     |'A'
   mov  bh,00h   ;Seite 0 ->BH                     |ausgeben
   int  10h      ;Interrupt 10h aufrufen           /
   mov  ch,4c    ;Funktion 4C -> CH         \Programm ordnungs-    
   int  21       ;Interrupt 21h aufrufen    /gem beenden
{ende}

Wie ihr seht, hab ich das Proggy halbwegs gut dokumentiert.

Im Interrupt 21h sind auch noch einige Funktionen verankert.
Diese habe ich aber nicht so gut dokumentiert, ihr mt also 
ein bisschen rumprobieren.


AH: |Funktion   |Eingabe          |Ausgabe
====|===========|=================|============================= 
02h |Zeichen    |DL:Zeichen       |   . /
    |anzeigen   |                 |    / .
----|-----------|-----------------|----------------------------- 
04h |Zeichen auf|DL:Zeichen       |   . /
    |AUX ausgebe|                 |    / .
----|-----------|-----------------|----------------------------- 
05h |Zeichen    |DL:Zeichen       |   . /
    |drucken    |                 |    / .
----|-----------|-----------------|-----------------------------
09h |String     |DS:DX            |   . /
    |ausgeben   |ZEIGER auf String|    / .


Segmente
**********

Segmente sind, wie im Ass-Kurs 2 oder 3 beschrieben, Teile
einer Adresse. In TP werden Sie so adressiert:
    
  memw[segment:offset]:=0;

In Assembler (oder ASS oder ASM) wird es (ungefhr) so 
adressiert:

  mov DX,segment     ;Segment-Addy ->DX
  mov DI,offset      ;Offset -Addy ->DI
  mov AX,wert        ;Wert         ->AX
  mov [DX:DI],AX     ;und schreiben             

  [Anmerkung von Kemil:
    Hier irrt sich Mc-F leider. Ist zwar nicht schlimm, aber
    immerhin: die letzte Zeile (mov [DX:di],ax) haut nicht hin,
    da man DX nicht als Segmentregister verwenden kann. Hier ein-
    fach DS, ES etc. benutzen!
  ]


oder: 

  mov AX,segment     ;Segment-Addy ->AX
  mov ES,AX          ;ES indirekt addressieren(WICHTIG!!)                   
  mov AX,offset      ;Offset-Addy  ->AX
  mov DI.AX          ;DI indirekt addressieren
  mov EAX,FFFFFFFF   ;Ext-AX mit 65 65 65 65 ('AAAA') laden  
  stosd              ;und schreiben           


Alle 2 Programme werden (sollten jedenfalls) das gleiche 
bewirken, wobei zu sagen (hh schreiben) ist, da die zweite
Routine schneller ist.


Segment           |Funktion
==================|=============================================
A000-B000         |Zustzliches VGA-Ram
B000-B800         |Monochrom-Ram
B800-C000         |CGA Ram
C000-C800         |BIOS fr GFX Karte
----------------------------------------------------------------

Segment 40h:Ofs

Ofs     |  Funktion
========|=======================================================
49h     | Videomodus
4Ah-4Bh | Zeichen + Zeilen-Anzahl
4Ch-4Dh | Byte / Bildschirmseite
4Eh-4Fh | Startoffset der aktiven Bildschirmseite
50h-5Fh | Cursorpositionen der 7 Bildschirmseiten
60h-61h | Start / Endzeile des Cursors
62h     | gerade aktive Bildschirmseite
63h-64h | Basisadresse (fr was eigentlich??)
65h     | Modusauswahlregister  (undokumentiert)
66h     | fr die Palette, ebenfals undokumentiert
84h     | Letzte Bildschirmseite \
85h     | Zeichenhhe            |} Nur EGA/VGA !!
87h     | Status Videocontroller /
A8h-B7h | Verwendet fr VGA/EGA (nicht weiter dokumentiert)
----------------------------------------------------------------

Port's
********

Port.No   |   Funktion
==========|=====================================================
2B0h-2DFh | Zusatz EGA-Karte
3B0h-3B7h | Hercules-Karte
3C0h-3CFh | EGA-Karte
3D0h-3D7h | CGA-Karte
----------------------------------------------------------------

Zum Schlu noch zwei Routinen wie man den Bildschirm lscht:

{start}
   mov AX,0B800    ;seg:ofs(=0B800) -> AX
   mov ES,AX       ;ES indirekt laden
   xor EDI,EDI     ;Ext-DI auf 0 setzen
   mov CX,1000     ;Counter(=1000)  -> CX
   xor EAX,EAX     ;Ext-AX mit 0 laden
   rep stosd       ;wiederhole CXmal AX in Speicher schreiben
       ;EDI wird dabei automatisch erhht(denke ich)
;Der Effekt dieser Routine ist, da der Bildschirmspeicher von 
;B800h-C000h  mit Nullen gefllt wird
{ende}

und die zweite:

{start}
   mov AX,000Fh     ;Funktion 0Fh ->AX
   int 10h          ;Interrupt  10h aufrufen
   mov AH,00h       ;Funktion 00h ->AX
   int 10h          ;Interrupt  10h aufrufen
;Hier wird Int 10h(funkt 0Fh) aufgerufen. In AL wird der Modus
;gespeichert und ber die Funktion 00h neu gesetzt ->CLRSCR
{ende}


So das solls fr diese Ausgabe gewesen sein von (bei 214 Zeilen)

                                                  Mc-F/No Group!
       (aber vielleicht willz ja mal jemand mit mir versuchen??)

PS: Interessiert sich wirklich  NIEMAND fr Assembler??
    Oder seit ihr nur zu faul mal was zu schreiben?

PS,Kemil: Wieso? Ich (und Gabriel) interessieren sich auf jeden
Fall fr diese Prospe. Ist das noch nicht durchgekommen? Aller-
dings habe zumindest ich noch keine Erfahrung mit 386'er Befehlen
bzw. mit den erweiterten Registern gemacht. Aber wenn Du an Er-
fahrungsaustausch interessiert bist, weit Du ja, wie Du mich
erreichst!


