Bildschirmbearbeitung --------------------- Ich habe heute (diese Ausgabe hehe) einfach mal als Grund genommen, um mal 'n bisschen ber Bilschirmausgaben zu labern. N„chste 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 l„sst 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 l„sst 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 w„hlen |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 mát 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 (ungef„hr) 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 |Zus„tzliches 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 | Zeichenh”he |} 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 l”scht: {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 erh”ht(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, weiát Du ja, wie Du mich erreichst!