Mauszeiger im SVGA Modus (und >640x480)



  • Hi,

    Nachdem ich eine kleinere Mausfunktion geschrieben habe,
    die einen Mauszeiger anzeigt, frage ich mich, wie ich den
    Mauszeiger bei Auflösungen über 640x480 einschalte:

    Hier meine Funktion für 640x480:

    mouse:
    
    ;Prüfe, ob Maus installiert
    mov ax,00h
    int 33h
    
    cmp ax,0FFFFh
    jne mouseerr
    jmp mouseok
    
    mouseerr:
    ret
    
    mouseok:
    
    mov ax,01h;
    int 33h;
    
    ;Set mouse X-Range
    mov ax,07h
    mov cx,0
    mov dx,screensizex
    int 33h
    
    ;Set mouse Y-Range
    mov ax,08h
    mov cx,0
    mov dx,screensizey
    int 33h
    
    ;Abtastrate verändern
    mov ax,1Ch
    mov bx,03 ;01 = 30/sec ... 02 = 50/sec ... 03 = 100/sec ... 04 = 200/sec
    int 33h
    
    ret
    

    Bei >640x480 stürzt damit nämlich das Programm ab. 🙄

    MfG,
    [Morpheus]



  • Du zeichnest ihn selber auf den Bildschirm.



  • ... darauf wäre ich ja nie gekommen ... :p 😉

    Ich wollte ja nur fragen, ob es eine einfachere Möglichkeit gibt. 😉

    MfG,
    [Morpheus]



  • Nö, gibt's nicht.



  • Also, ich komm hier einfach nicht weiter.

    Kann mir jemand sagen, wie ich im SVGA-Modus die Farbe
    eines Pixels ändern kann (>640x480)? Bis 640x480 kann ich
    das auch noch. 🙄

    Wie würde das z.B. im Grafikmodus 105h gehen?

    MfG,
    [Morpheus]



  • Wenn du noch dazu schreibst, welche Farbtiefe das ist. Und ich nehme an, du verwendest VESA 1 und nicht 2, sonst wäre es glaub ich Modus 4105h, IIRC.



  • 256 Farben und VESA 1. 😉

    MfG,
    [Morpheus]



  • Dass jedes Pixel ein Byte ist, sollte ja klar sein. Du musst über eine VESA-Funktion herausfinden, an welcher Speicheradresse ein schreibbares Window liegt und wie groß es ist. Dann verschiebst du dieses Window mittels einer anderen VESA-Funktion an die Stelle, an der du Pixel ändern möchtest und schreibst diese ins Window hinein.



  • Hmmm... das mit dem Window verstehe ich noch nicht ganz, aber ich habe jetzt doch eine kleine Funktion gefunden, die einen Pixel verändert:

    ;<--Hier der Wechsel zu 1024x768x8
    mov bx,0xA000  
    mov es,bx          	 
    
    mov ecx,0x00		
    mov al,16  ;Farbanzahl?
    mov byte [es:ecx],al  		
    
    mov ecx,0x00		
    mov al,1  ;Farbwert
    mov byte [es:ecx+15000],al  ;15000 ist die Pixelnummer
    mov ecx,eax
    

    Meintest du sowas?

    [EDIT:]
    Hoppla, das geht auch nur bis zu einem bestimmten Punkt.
    Danach schmiert das Programm ab. 😞
    [/EDIT]

    MfG,
    [Morpheus]



  • Such dir mal eine VESA-Doku. Darin ist das mit dem Window erklärt. Nachdem es ja maximal 64KB groß sein kann (A000-B000, meistens ist es aber kleiner), kannst du nie den ganzen Bildschirm auf einmal adressieren und musst es daher mit einer VESA-Funktion herumschieben.



  • Hi.

    Zu der Sache mit den Windows:
    Eigentlich ganz einfach Rechnung: Ein Segment ist im RealMode 64KByte gross - von daher ist auch das Adressieren mit 32Bit leicht unsinnig.
    Der FrameBuffer fuer zB. 1024x768x8Bit ist 1024*768=786432Byte=768kByte gross.
    Das ist fast schon so viel, wie dir im RealMode ueberhaupt an adressierbarem Speicher zur Verfuegung steht (naemlich 1MB bei eingeschalteter A20).
    Sollte also klar sein, dass du im RealMode nicht einfach so an den ganzen FrameBuffer rankommst. Dafuer gibt es diese sinnvolle Erfindung der Speicherfenster fuer VESA. Hier wird ein kleiner (meist der Einfachheit halber 64KByte grosser) Teil des Framebuffers in einen im RealMode adressierbaren Teil des Speichers gemapt (meist A0000).

    VESA-Funktion 01h gibt dir uA. Infos darueber, wohin dieses Fenster im RM gemapt wird, wie gross es ist, und in welchen Abstaeden du das Fenster im FrameBuffer bewegen kannst (meist auch 64KByte).
    Mit VESA-Funktion 05h kannst du das Speicherfenster im FrameBuffer verschieben und so auswaehlen, welcher Teil des FrameBuffers in den RealMode-Speicher gemapt werden soll.

    Zum Einstieg finde ich diese Seite zum Thema VESA nicht schlecht.

    BTW:
    Wie konntest du in einem Modus mit 640x480x>4 vernuenftig arbeiten, wenn du nicht weisst, wie das mit den Windows funktioniert? 😕



  • Danke. Ich gucke mir die Seite mal an.

    BTW:
    Wie konntest du in einem Modus mit 640x480x>4 vernuenftig arbeiten, wenn du nicht weisst, wie das mit den Windows funktioniert?

    Ich weiss nicht genau. Es hat einfach funktioniert. 😃

    MfG,
    [Morpheus]



  • So. Ich habe jetzt schon mal eine Funktion, die sogar bei
    1280x1024x16 den Bildschirm einfärben kann.

    mov dx,0xa000
    mov ds,dx              ;sets up registers
    call window
    rain:
    xor dx,dx      ;(pages-1)
    
    mouse:
    push dx
    call window
    xor bx,bx
    mov al,0x3453 ;grau=0x3453 <-- Farbe
    call dog
    pop dx
    cmp dx,59                ; devide the screen size by 64k, -1 and replace the 4 with the number.
    je rain
    inc dx
    mov ah,01h
    call mouse
    call mouse
    
    window:
    mov ax,4f05h    ;vesa 1 window select
    mov bx,0
    int 10h        ;dx is  the reqired window
    xor bx,bx
    ret
    
    dog:        ;(4*2^16)+45056 pixels
    mov [bx],al
    inc bx
    cmp bx,$00000
    jne dog
    ret
    

    In welchem Format muss jetzt der Farbwert sein, wenn ich
    ihn mit Hilfe von RGB-Werten erstellen will.
    (z.B. 0F0h ist weiss und in RGB (255,255,255))

    Wie ist das z.B. bei blau (0,0,255)?

    MfG,
    [Morpheus]



  • Sry, aber komischer Code... Der funktioniert so? 😕
    Na wie auch immer:
    Wie du in Modi ohne Palette die Farbwerte zu berechnen hast, sagt dir die VESA-Funktion 01h. Das kann unter Umstaenden von Karte zu Karte sehr unterschiedlich sein (bei einigen 32Bit-Modi laesst meine GeForce zB. 8Bit ungenutzt. ⚠ ).
    Stichwort:

    RedMaskSize         byte    	; size of direct color red mask in bits
            RedFieldPosition    byte    	; bit position of LSB of red mask
            GreenMaskSize       byte    	; size of direct color green mask in bits
            GreenFieldPosition  byte    	; bit position of LSB of green mask
            BlueMaskSize        byte    	; size of direct color blue mask in bits
            BlueFieldPosition
    

    Schau mal auf die von mir verlinkte Tutorialseite. Da steht, wie die RGB-Felder bei einem 16Bit-Pixel meist so verteilt sind.


  • Mod

    der code ist wirklich merkwürdig. sieht wie eine endlosrekursion aus. und bei mov al,0x3453 bekommst du keine warnung vom assembler?

    dog:        ;(4*2^16)+45056 pixels
    mov [bx],al
    inc bx
    cmp bx,$00000
    jne dog
    ret
    

    die cmp instruktion ist hier überflüssig. inc setzt das zero-flag bereits. ausserdem sollte man hier über loop-unrolling nachdenken - vesa ist schliesslich schon langsam genug. etwa so:

    dog:
    mov ah, al
    dog2:
    mov [bx],ax
    mov [bx+2], ax
    mov [bx+4], ax
    mov [bx+6], ax
    add bx, 8
    jnc dog2
    ret
    

    noch besser dürfte ein rep stosw sein



  • Du kannst auch nicht davon ausgehen, dass das Schreib-Window immer genau bei 0xa000 beginnt. Du musst erst mal abfragen, wo das Window überhaupt liegt und wie groß es ist.



  • Den Code hatte ich im Internet gefunden und nicht selbstgeschrieben.

    sieht wie eine endlosrekursion aus. und bei mov al,0x3453 bekommst du keine warnung vom assembler?

    Nein. Funktioniert prima. 😋

    Ringding schrieb:

    Du kannst auch nicht davon ausgehen, dass das Schreib-Window immer genau bei 0xa000 beginnt. Du musst erst mal abfragen, wo das Window überhaupt liegt und wie groß es ist.

    Steht das nicht auch im VESA Infoblock (Function 01h)? Ich habe den leider noch nicht
    in meinen Code eingefügt, da die Beispiele, die ich bisher gefunden habe,
    wohl alle für TASM/MASM sind. 😞
    Hat jemand ein NASM Beispiel?

    Sry, aber komischer Code... Der funktioniert so? 😕

    Funktioniert prima. 🙄

    MfG,
    [Morpheus]



  • [Morpheus] schrieb:

    Den Code hatte ich im Internet gefunden und nicht selbstgeschrieben.

    In diesem Fall => Loeschen, ist ziemlich grosser Mist.

    [Morpheus] schrieb:

    Funktioniert prima.

    In deinem OS kann dieser Code wohl wirklich den Bildschirm in einem VESA-Modus in einer Farbe einfaerben, mehr geht damit aber nicht. Nach kurzer Zeit verursacht dieser Code naemlich einen Stackueberlauf.

    PS(ein bissel OT) :
    Sry, dass ich mal wieder den Moralprediger vorkramen muss, aber bei dem was du hier abziehst, musste ich mir einfach gerade unwillkuerlich an den Kopf packen.
    Ist ja sehr loeblich, dass du im Gegensatz zu einigen anderen Gestalten hier deine Codeschnippsel teilweise noch selbst zusammensammelst, um dein OS zu bauen, anstatt konstenlose Fertigloesungen zu erwarten, aber wenn du dich nichtmal gut genug in Assembler auskennst, um zu erkennen, dass der Code da oben offensichtlich Schrott ist, solltest du uU. mal eher darueber nachdenken, zum Ueben selbst gezielt einige einfachere/kleinere Programme (also auf jeden Fall ohne VESA-Grafik 😉 ) selbst zu coden - dh. ohne die Hilfe von "Beispielcodes", die du scheinbar einfach zum wahllosen Ausschlachten via C&P verwendest.
    Ich weiss ja nicht, was fuer Intentionen du hast, dein OS zusammenzuklicken, aber lernen wirst du auf die Weise dabei IMHO nichts. Wenn's dann funktioniert waere das IMHO auch nur Fortuna, oder einigen gelangweilten Forensuchtis zu verdanken... 😃

    Nur meine Meinung - ich finde so ein C&P-Gescripte nunmal absolut zum K*****. Nicht persoenlich nehmen, aber vielleicht mal drueber nachdenken. 💡
    Sollte ich dich falsch eingeschaetzt haben, kannst du mich natuerlich auch gern in die Pfanne hauen. 😉



  • Naja gut, ich sehe es ja ein. 😉

    Ich weiss jetzt nicht, ob du das mit dem "zusammenklicken" nur auf
    meine Assemblercodes bezogen hast oder auf meine allgemeine Programmierung,
    aber ich bin leider bei Assembler noch ein Anfänger und habe mich mit
    VESA-Programmierung wohl ein wenig verschätzt.

    Vielleicht sollte ich dann ja wirklich lieber bei C++ bleiben.
    Das kann ich wenigstens und da brauche ich nichts "zusammenklicken".
    Das war ja nur bei meinem VESA-Teil das Problem, dass das
    nicht so richtig funktioniert hat. Der Rest, den ich bisher geschrieben
    habe, ist ein wenig anderes ... aber das tut jetzt nichts zur Sache.

    Okay ... dann schließe das Thema von mir aus. :p

    MfG,
    [Morpheus]

    P.S: Trotzdem vielen Dank an alle, die hier ihren Beitrag abgegeben haben.



  • Du kannst ja VESA auch von C++ aus verwenden (unter DOS), das ist schon etwas weniger mühsam. int86() oder wie auch immer das heißt brauchst du halt.


Anmelden zum Antworten