Autor Thema: VESA VBE Framebuffer-Fehler  (Gelesen 7617 mal)

Al3x

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« am: 18. April 2010, 17:28 »
Hallo,

ich programmiere in Assembler mit fasm und bin nun im protected mode mit VESA 640*480*24 (mode 0112h). VirtualBox bestätigt mir den Modus.

1. Wieso muss man 4112h schreiben statt 0112h?

2. Wie lautet der mode für 32 bit-bit? 0129h laut http://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Other_commonly_available_modes
funktioniert nicht.

3. Dies ist der Code zum schreiben von Pixeln:

Display_Pixel:

mov edi,[ModeInfo_PhysBasePtr]

mov ebx, 640 ; gewünschte Breite
mov ecx, 480 ; gewünschte Höhe

mov ax, 0xfafa ; untere 16 Bits der Farbe
mov dl, 0x00 ; obere 8 Bits der Farbe

Stapel:
push edi
push ebx

Zeile:
add edi,3
mov [edi-3],ax
mov [edi-1],dl
dec ebx
jnz Zeile    ; springt solange nach Zeile, bis letztes Rechenergebnis null ergibt/Zero Flag gesetzt ist
pop ebx
pop edi
add edi, ModeInfo_BytesPerScanLine
loop Stapel    ; zieht von ecx 1 ab; solange ecx nicht null ist, wird nach Stapel gesprungen.

ret 

Nun ist das erste Pixel, das eingefärbt wird nicht das erste oben links?/rechts?, sondern es ist mitten in der ersten Zeile (siehe http://www.abload.de/image.php?img=capture_04182010_17262vfd5.jpg ). Daraus schließe, dass ModeInfo_PhysBasePtr auf eine falsche Adresse zeigt.  :? Aber wieso?
Wenn ich nun von edi 1566 (dezimal) abziehe, ist das erste Pixel auch das oberste linke, doch die letzte Zeile wird nur zur Hälfte gefüllt, wobei das letzte Pixel blau ist.

4. Wenn ich 480 bei [3] als Höhe eingebe, wird aber nur etwa ein drittel geefärbt  :?

Ich hoffe, dass ihr mir helfen könnt.
Vielen Dank im Voraus!!!
« Letzte Änderung: 18. April 2010, 17:43 von Al3x »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 18. April 2010, 17:50 »
1. Wieso muss man 4112h schreiben statt 0112h?
Die Zahl 4112h unterscheidet sich von 0112h dadurch das Bit 14 gesetzt ist. Das weist die Grafikkarte an den "Linear Framebuffer" zu nutzen. Das bedeutet du kannst auf Framebuffer an einem Stück zugreifen, anstatt nur auf einen Teil zu einer bestimmten Zeit.

Zitat
2. Wie lautet der mode für 32 bit-bit? 0129h laut http://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Other_commonly_available_modes
funktioniert nicht.
Du kannst die verfügbaren Modi mit Funktion 4F00h und 4F01h enumerieren, und nachschauen, ob die Grafikkarte diesen Modus zur Verfügung stellt.
Dieser Text wird unter jedem Beitrag angezeigt.

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #2 am: 18. April 2010, 17:56 »
4. Wenn ich 480 bei [3] als Höhe eingebe, wird aber nur etwa ein drittel geefärbt  :?
Hm, nur so Troubleshooting: Hast du das A20-Gate aktiviert?
(Auch wenn du im PM bist, stelle ich diese Frage lieber mal :-D)
« Letzte Änderung: 18. April 2010, 17:59 von XanClic »

Al3x

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 18. April 2010, 18:00 »
Ja, hab ich. Ich denke, dass es auch funktioniert.
enable_A20:
        pusha
        cli                                    ; Disable all irqs
        cld
        mov   al,255                           ; Mask all irqs
        out   0xa1,al
        out   0x21,al
l.5:    in    al,0x64                          ; Enable A20
        test  al,2                             ; Test the buffer full flag
        jnz   l.5                              ; Loop until buffer is empty
        mov   al,0xD1                          ; Keyboard: write to output port
        out   0x64,al                          ; Output command to keyboard
l.6:    in    al,0x64                         
        test  al,2
        jnz   l.6                              ; Wait 'till buffer is empty again
        mov   al,0xDF                          ; keyboard: set A20
        out   0x60,al                          ; Send it to the keyboard controller
        mov   cx,14h
l.7:                                           ; this is approx. a 25uS delay to wait
        out   0edh,ax                          ; for the kb controler to execute our
        loop  l.7                              ; command.
        sti
        popa
        ret   


EDIT: Ich hab mal alles hochgeladen:

http://dl.dropbox.com/u/1802708/Bild.zip
« Letzte Änderung: 18. April 2010, 18:15 von Al3x »

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 21. April 2010, 20:11 »
Hallo,


2. Wie lautet der mode für 32 bit-bit?
Das VESA-BIOS kann Dir genau sagen welche Modi es alle hat. Dazu musst Du Dir ne Liste generieren und den passenden Modus auswählen.
Damit hab ich mal 1024*768*32bpp (mit 4 Bytes pro Pixel macht das einfach mehr Spaß) gemacht und das lief in verschiedenen Emulatoren und auf etlichen echten PCs problemlos.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 21. April 2010, 21:42 »
Du hast vergessen, dass du in der GDT rumfummelst, und die Basisadressen änderst. Das bedeutet, wenn du auf die lineare Adresse 0xe0000000 (da wo halt der Linear Frame Buffer ist) zugreifen willst, musst du entweder einen Selektor mit Basis 0 nehmen, oder die andere Basis berücksichtigen.

Wenn du in deiner Display_Pixel funktion das Schreiben in den Frame Buffer so machst (Selektor mit Basis 0 laden), klappt es:

push cx
mov cx, 0x08 ; eigentlich linear_sel
mov ds, cx
mov [edi-3],ax
mov [edi-1],dl
mov cx, 0x18 ; eigentlich sys_data
mov ds, cx
pop cx

Optimieren darfste das selbst.
« Letzte Änderung: 21. April 2010, 23:01 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

 

Einloggen