Bildschirmasugabe in Vesa



  • Hallo,
    habe mir einen Bootloader geschrieben und einen kleinen Karnel!
    Hier der Code des Kernels:

    MOV AH,4FH           ;AH = 4F (Vesa-Adresse) setzen
            MOV AL,02H           ;AL = 02 setzen
            MOV BX,103H          ;Setzt Auslösung 800x600x256 = Mode 103
            INT 10H              ;Video-Modus starten
    

    Diese vier Zeilen sind mein "Kernel". Nun bräuchte ich ein gutes Beispiel, wie ich auf diesem Bildschirm ein Pixel setze, am besten sollte das beispiel an meinen Kernel-Code anghängt werden können. Außerdem würde ich gerne richtige Bilder anzeigen lassen, also bitmaps darstellen, wie bekomme ich das hin? Vielen vielen Dank schonmal für eure Bemühungen und wenn es geht verweist bitte nicht irgendwo drauf, sondern erklärt es mir nach Möglichkeit hier. Danke!



  • Dein Kernel sieht doch sicherlich vor, solche Funktionen in Treiber auszulagern.



  • 'Ja, aber dafür würde ich tortzdem ganz gerne wissen, wie ich solche punkte setze, oder bitmaps erstellen kann auf dem bildschirm.danke!



  • Hi.

    Schreibst du wie im VGA Mode 13h einfach Byteweise in den Speicher bei A0000h.
    Du wirst wahrscheinlich erkannt haben, dass die max. 64KByte in diesem Segment nicht ausreichen, um 800*600Pixel unterzubringen. Tatsaechlich verhaelt es sich so, dass hier Teile des Framebuffers eingeblendet werden.
    Um diesen Speicherausschnitt zu wechseln, gibt es die VESA-Funktion 05h. Dort kannst du in dx die Position des Speicherfensters im Framebuffer einstellen.
    In welcher Einheit dx zaehlt - also mit welcher Zahl dx multipliziert werden muss, um das tatsaechliche Offset des Speicherfensters im FrameBuffer zu erhalten - erfaehrst du von VESA Funktion 01h. Ist das Word bei Offset 4 im zurueckgegebenen Buffer. In diesem Buffer werden uebrigens auch noch andere wichtige Infos zurueckgegeben - um ein Studium eines Tutorials o.Ae. wirst du nicht herumkommen. Ich hoffe das war erstmal halbwegs klar. Es folgt als Beispiel in Auszuegen ein ~5Jahre alter Pascal-Code von mir mit Assemblereinstreuungen 😉 :

    Type
    
    VesaInfoType=Record
     ModeAttributes:Word;   {0}
     WinAAttr,WinBAttr:Byte;{2}
     WinGranular,WinSize,WinASeg,WinBSeg:Word; {3,5,7,9}
     WinFuncPtr:Pointer;  {11}
     BytesPScl,XResu,YResu:Word; {15,17,19}
     XCharS,YCharS,NrOfPlans,BitsPxl,NrOfBanx,MemModl, {21,22,23,24,25,26}
     BankSize,NrOfImgPages,Resrv0,RedMskSze,RedFldPos,GrnMskSze,GrnFldPos,{27,28,29,30,31,32,33}
     BluMskSze,BluFldPos,RsvdMskSze,DirectClrInfo:Byte;{34,35,36,37}
     Resrv1:Array[1..216] of Byte; {38}
    End;
    
    Var
    VesaInfo:VesaInfoType;
    Granular:Word;
    LastBank:Word;
    
    Procedure GetVESAInfo(Mode:Word);
    Var
    VIS,VIO:Word;
    Begin
    VIS:=Seg(VesaInfo);
    VIO:=Ofs(VesaInfo);
    Asm
     Mov Es,VIS
     Mov Di,VIO
     Mov Ax,4F01h
     Mov Cx,ModeType
     Int 10h
    End;
    End;
    
    Procedure PutPixel(X,Y,C:Word);
    Var
    Page:Word;
    Index:Word;
    L:LongInt;
    LGranular:LongInt;
    Begin
    {Granular ist VesaInfo.WinGranular - wird bei 0 aber auf FFFF gesetzt...}
    If X>VESAInfo.XResu then Exit;
    If Y>VesaInfo.YResu then Exit;
    If VESAInfo.BitsPXL=8 then Begin
     If VESAInfo.XResu<=320 then Begin
      Asm
       mov ax,$A000
       mov es,ax
       mov ax,Y
       mov dx,320
       mul dx
       mov dx,X
       add ax,dx
       mov di,ax
       mov ax,word ptr (c)
       mov es:[di],al
      End;
     End else Begin
      LGranular:=Granular;
      If Y>VESAInfo.YResu-1 then Y:=VESAInfo.YResu;
      L:=Y;
      L:=L*VESAInfo.XResu;
      If X>VESAInfo.XResu-1 then X:=VESAInfo.XResu;
      Inc(L,X);
      Page:=L div (LGranular shl 10);
      Asm
       Mov Dx,Page
       Mov Ax,LastBank
       Cmp Ax,Dx
       Jz @samebank
       Mov Ax,$4F05
       Mov Bh,0
       Mov Bl,0
       Int $10
       Mov LastBank,Dx
       @samebank:
      End;
       Index:=L-(Page*(LGranular shl 10));
      Asm
       mov ax,$A000
       mov es,ax
       mov ax,Index
       mov di,ax
       mov ax,word ptr (c)
       mov es:[di],al
      End;
     End;
    End else if VESAInfo.BitsPxl=16 then Begin
     LGranular:=Granular;
     L:=Y;
     L:=L*(VESAInfo.XResu shl 1);
     Inc(L,X shl 1);
     Page:=L div (LGranular shl 10);
     Asm
      Mov Dx,Page
      Mov Ax,LastBank
      Cmp Ax,Dx
      Jz @samebank
      Mov Ax,$4F05
      Mov Bh,0
      Mov Bl,0
      Int $10
      Mov LastBank,Dx
      @samebank:
     End;
      Index:=L-(Page*(LGranular shl 10));
     Asm
      mov ax,$A000
      mov es,ax
      mov ax,Index
      mov di,ax
      mov ax,word ptr (C)
      mov es:[di],ax
     End;
    {End else if VESAInfo.BitsPxl=24 then Begin
     LGranular:=Granular;
     L:=Y;
     L:=L*(VESAInfo.XResu*3);
     Inc(L,X*3);
     Page:=L div (LGranular shl 10);
     Asm
      Mov Dx,Page
      Mov Ax,LastBank
      Cmp Ax,Dx
      Jz @samebank
      Mov Ax,$4F05
      Mov Bh,0
      Mov Bl,0
      Int $10
      Mov LastBank,Dx
      @samebank:
     End;
      Index:=L-(Page*(LGranular shl 10));
     Asm
      mov ax,$A000
      mov es,ax
      mov ax,Index
      mov di,ax
      mov ax,word ptr(C)
      mov es:[di],ax
      add di,2
      mov al,word ptr(C+2)
     End;}
    End;
    End;
    

    Ist vielleicht halbwegs verstaendlich... Ich wuerde dir aber davon abraten, C&P zu machen - dafuer ist der Code einfach zu scheisse. 💡
    Als Begleitlektuere empfehle ich Vesa BIOS Example. Page 1: - ist zwar nicht mehr auf dem neusten Stand - reicht aber zum Einstieg allemal.



  • Vielen, vielen Dank, hast mir echt geholfen...


  • Mod

    edit: das wolltest du gar nicht wissen.


Anmelden zum Antworten