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...
-
edit: das wolltest du gar nicht wissen.