Bildschirm mit Farben füllen - wie geht das?
-
Ich habe ein kurzes Programm in Assembler geschrieben.
Es soll den Bildschirm in allen 256 Farben füllen.
Leider tut es das nicht ganz, denn es werden nur ca. 4 Farben angezeigt.
Ich habe ein ähnliches Programm geschrieben, das den Bildschirm nur einmal füllt und zwar mit einer anderen Farbe in jeder Zeile. Das klappt überragend und zeigt einen gangen Schirm voller prächtiger Farben.
Aber wenn ich den Schirm in 256 Durchgängen mit je einer Farben ganz (d.h. es sind ca. 75% ) fülle, dann bricht das Programm nach der 4. Farbe ab.
Ich kann leider keinen Fehler finden. Denn an den Port Befehlen liegt es wohl kaum, da das ja schon mal geklappt hat und einen Schleifenfehler oder sowas ähnliches finde ich nicht.
Wer kann mir helfen?--------------------------------------------------------------------------------
Data SEGMENT WORD 'DATA'
Msg DB 13,10,'Nun wird gleich der Video-Grafik Modus eingeschaltet ! Danach wird der Bildschirm direkt mit Maschinensprache beschrieben! (Schnell, wa?) ',13,10,''
Warten1 DW 0
Farbe DW 0
Farbe1 DB 0
Fuell DW 12*256*16
Data ENDSCode SEGMENT BYTE 'CODE'
ASSUME CS:CODE, DS:DATA
Start: mov ax, DATA ; Segmentgrenze des Segmentes DATA in AX
mov ds, ax ; AX in DS kopieren -> Segmentgrenze in DS
mov dx,OFFSET Msg ; Offset des "Labels" Msg in DATA in DX
mov ah, 009h ; AH mit Wert 9 belegen
int 021h ; Interrupt $21 aufrufenCALL Warten
mov ax, 00013h
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 100
mov cx, 100
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 102
mov cx, 100
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 101
mov cx, 101
int 010hmov dx,3ceh
mov ax,04005h
out dx,ax
mov al,0003h
out dx,ax
mov ax,00108h
out dx,ax
mov ax,0f00h
out dx,ax
mov ax,0f01h
out dx,axmov dx,0a000h
mov es,dx
mov di,00000h
Fuellen:
mov ax,es:di
xor ax,0ffffh
mov es:di,ax
add di,002h
cmp di, Fuell
jne Fuellensub Fuell, 2
mov di,0
mov dx,03ceh
mov ax,00008h
mov ah,Farbe1
out dx,axadd Farbe1,1
cmp Farbe1,0
jne FuellenCALL Warten
mov ax, 00003h
int 010hmov ax, DATA ; Segmentgrenze des Segmentes DATA in AX
mov ds, ax ; AX in DS kopieren -> Segmentgrenze in DS
mov dx,OFFSET Msg2 ; Offset des "Labels" Msg in DATA in DX
mov ah, 009h ; AH mit Wert 9 belegen
int 021h ; Interrupt $21 aufrufenEnde: mov ah, 04Ch ; Funktion 4Ch
int 021h ; Interrupt 21Warten PROC near
mov Warten1,0
Schleife:
mov ax, 0
Schleife2:
add ax,1
cmp ax, 0fff0h ; ein wenig
jne Schleife2 ; warten
add Warten1,1
cmp Warten1, 064e0h ; ein wenig
jne Schleife ; warten
retWarten ENDP
Code ENDS
END Start
-
Was sollen die ganzen Operationen zw. initialisieren des Mode 13 und dem eigentl. Füllen?
Habe auch mal so ein Programm geschrieben, sa in etwa so aus (ohne Funktionsgarantie):
ScreenSize equ 320 * 200 ScreenAddrSeg equ 0A00h ScreenAddrOff equ 0000h ScreenMode equ 13h ScreenModeIntFunc equ 00h ScreenModeInt equ 10h Color equ 0F0h ;nur so als Bsp. ExitCode equ 4C00h ExitInt equ 21h ;---------------- start: mov ax,(ScreenModeIntFunc<<8)+ScreenMode int ScreenModeInt mov cx, ScreenSize/4 mov ax, ScreenAddrSeg mov es, ax mov di, ScreenAddrOff mov eax, Color<<24+Color<<16+Color<<8+Color rep stosd exit: mov ax, ExitCode [edit]upsy, hier war bis gerade noch ein Fehler, Dank an Nobuo T[/edit] int ExitInt
[ Dieser Beitrag wurde am 04.11.2002 um 16:30 Uhr von -bg- editiert. ]
[ Dieser Beitrag wurde am 25.11.2002 um 15:36 Uhr von -bg- editiert. ]
-
@-bg-: es geht auch umstaendlich, oder?
Ausserdem gehoert der Parameter fuer int 21h in ax.@<EricFa>:
aehm, ja, was sollen diese ganzen Kommandos an den Graphic-Controller genau bewirken?
Bin irgendwie zu faul meine VGA-Referenz nochmal durchzuwuehlen
-
Da sind noch die Befehle, um die drei blauen Punkte auf den Bildschirm zu schreiben. Die sind noch von vorherigen versuchen da geblieben und haben eigentlich keine Funktion.
Dann sind da noch die Portbefehle:mov dx,3ceh Graphics Controller adressieren
mov ax,04005h Graphics Mode (ups da sit ja 'ne Null zu viel- sollte es das sein?)
out dx,ax
mov al,0003h function select
out dx,ax
mov ax,00108h bit mask
out dx,ax
mov ax,0f00h set/reset - Farbwert
out dx,ax
mov ax,0f01h enable set/reset
out dx,ax
-
Dieses Programm, ein etwas älteres funktioniert.
Es füllt den Schirm in allen 256 Farben mit je einer Farbe pro Zeile.Data SEGMENT WORD 'DATA'
Msg DB 13,10,'Nun wird gleich der Video-Grafik Modus eingeschaltet ! Danach wird der Bildschirm direkt mit Maschinensprache beschrieben! (Schnell, wa?) ',13,10,''
Warten DW 0
Farbe DW 0
Farbe1 DB 0
Linie DW 0
Data ENDSCode SEGMENT BYTE 'CODE'
ASSUME CS:CODE, DS:DATA
Start: mov ax, DATA ; Segmentgrenze des Segmentes DATA in AX
mov ds, ax ; AX in DS kopieren -> Segmentgrenze in DS
mov dx,OFFSET Msg ; Offset des "Labels" Msg in DATA in DX
mov ah, 009h ; AH mit Wert 9 belegen
int 021h ; Interrupt $21 aufrufenmov Warten,0
Schlei_2te:
mov ax, 0
Schleife:
add ax,1
cmp ax, 0fff0h ; ein wenig
jne Schleife ; warten
add Warten,1
cmp Warten, 044e0h ; ein wenig
jne Schlei_2te ; wartenmov ax, 00013h
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 100
mov cx, 100
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 102
mov cx, 100
int 010hmov ax, 00c01h
mov bh, 00
mov dx, 101
mov cx, 101
int 010hmov dx,3ceh
mov ax,04005h (hier sind es auch 4005 muesste also OK sein)
out dx,ax
mov al,0003h
out dx,ax
mov ax,00008h
out dx,ax
mov ax,0f00h
out dx,ax
mov ax,0f01h
out dx,axmov dx,0a000h
mov es,dx
mov di,00000h
Fuellen:
mov ax,es:di
xor ax,0ffffh
mov es:di,ax
add di,002h
add Linie,1
cmp Linie,160
jne Fuellen
mov Linie,0mov dx,3ceh
mov ax,00008h
mov ah,Farbe1
out dx,axadd Farbe1,1
cmp Farbe1,190
jne Fuellenmov Farbe,0
Schleife3_3:
mov dx, 1
Schleife3_2:
mov cx, 1
Schleife3_1:
mov ax,Farbe
add ax, 00c00h
mov bh, 00
; int 010h
add cx, 1
cmp cx, 300
jne Schleife3_1
add dx, 1
cmp dx, 200
jne Schleife3_2
add Farbe,1
cmp Farbe,258
jne Schleife3_3mov Warten,0
Schlei2_2te:
mov ax, 0
Schleife2:
add ax,1
cmp ax, 0fff0h ; ein wenig
jne Schleife2 ; warten
add Warten,1
cmp Warten, 0e4e0h ; ein wenig
jne Schlei2_2te ; wartenmov ax, 00003h
int 010hmov ax, DATA ; Segmentgrenze des Segmentes DATA in AX
mov ds, ax ; AX in DS kopieren -> Segmentgrenze in DS
mov dx,OFFSET Msg2 ; Offset des "Labels" Msg in DATA in DX
mov ah, 009h ; AH mit Wert 9 belegen
int 021h ; Interrupt $21 aufrufenEnde: mov ah, 04Ch ; Funktion 4Ch
int 021h ; Interrupt 21Code ENDS
END Start
-
Niemand hier, der sich auskennt?
-
was hast du denn für ein OS, also wo läuft dein Prog?
könntest du vielleicht nochmal die Wesentlichen Teile aufzeigen (also ohne überflüssige I/Os)?
Funktionieren denn die anderen Varianten die wir aufgezeigt haben bei dir?mfg
-bg-
-
Hier ist der wesentliche Teil mit den Portbefehlen und der Füllroutine.
Hoffe es ist ausführlich genug beschrieben.mov dx,3ceh Graphics Controller
mov ax,04005h Graphics Mode -> VGA 256 Farben Modus
out dx,ax
mov al,0003h Funktion Select -> keine Verknüpfung
out dx,ax
mov ax,00108h Bit Mask -> 1 für Farbe 2
out dx,ax
mov ax,0f00h Set/Reset -> alle 4 Bitplanes
out dx,ax
mov ax,0f01h Enable Set/Reset -> alle 4 Bitplanes
out dx,axmov dx,0a000h Adresse Bitmaps
mov es,dx
mov di,00000h Erste Speicherstelle
Fuellen:
mov ax,es:di word aus Bitmap lesen
xor ax,0ffffh Farbe in Bits umrechnen
mov es:di,ax und in den Speicher schreiben
add di,002h nächstes word
cmp di, Fuell diese Farbe schon fertig?
jne Fuellensub Fuell, 2 bei der nächsten Farbe 2 Byte weniger malen
mov di,0 Index zurücksetzten
mov dx,03ceh Graphics controller
mov ax,00008h Bitmask
mov ah,Farbe1 Farbwert
out dx,ax in den port schreibenadd Farbe1,1 erhöhten Farbwert merken
cmp Farbe1,0 alle Farben durch?
jne Fuellen
-
Mal abgesehen davon, dass ich diese Methode, bestimmte Farben zu setzen fuer "etwas" umstaendlich halte, verstehe ich diese Zeilen noch net so ganz:
Original erstellt von <wesentliche Teile>
**mov ax,es:di word aus Bitmap lesen
xor ax,0ffffh Farbe in Bits umrechnen
mov es:di,ax und in den Speicher schreiben
**Waere es nicht sinnvoller, den Speicher stattdessen einfach immer wieder auf FFh zu setzen?
So funktionierte das ganze bei mir zumindest schon so ungefaehr... Aus irgendeinem Grund lieferten 3 Bitplanes aber komische Farbwerte zurueck...
Die Schleife zur Aktualisierung des Speichers sollte so zumindest funktionieren...
-
Mal abgesehen davon, dass ich diese Methode, bestimmte Farben zu setzen >fuer "etwas" umstaendlich halte, verstehe ich diese Zeilen noch net so ganz:
Habe das für spätere Zwecke so gemacht, falls ich die vorhadenen Punkte noch mit umsetzen will.
Original erstellt von <wesentliche Teile>
mov ax,es:di word aus Bitmap lesen
xor ax,0ffffh Farbe in Bits umrechnen
mov es:di,ax und in den Speicher schreiben
Liest verknüpft und schreibt wieder zurück in den Grafikspeicher.
Waere es nicht sinnvoller, den Speicher stattdessen einfach immer wieder auf >FFh zu setzen?
Ja, mov ax,0ffffh wäre auch ok. Bringt aber im Endeffekt dasselbe.
So funktionierte das ganze bei mir zumindest schon so ungefaehr... Aus
Wie ungefähr?
irgendeinem Grund lieferten 3 Bitplanes aber komische Farbwerte zurueck...
3? Das sind 4 Bitplanes.
Die Schleife zur Aktualisierung des Speichers sollte so zumindest >funktionieren...
Wie oben schon gesagt. Das eine Programm, das so ähnlich ist, funktioniert.
Es füllt aber jede Zeile mit einer anderen Farbe. Bisher habe ich es noch nicht richtig hinbekommen, dass der Prozessor den gesamten Bildschirm mit nur einer Farbe korrekt füllt.
Da ein Farbpunkt korrekt gesetzt wird muss es anversich an der Schleife und an den Weiterzähl-Befehlen liegen.
-
Weiss keiner Bescheid?