Super VGA Programmierung - wie setzte ich Punkte?



  • wenn du an die hardware willst, dann gleich ein hinweis: da gibts mehrere versch. chips, die sich nicht mit einem universal-treiber ansteuern lassen (und das will ja VESA eigentlich!) d.h. du müsstest für jeden chipsatz (ATI, Trident, Tseng ....) einen eig. treiber schreiben, die entsprechende karte erkennen und den richtigen treiber laden. da ist es wahrscheinlich doch besser, VESA zu verwenden, oder?? ich persönlich habe mich zumindest in meiner GUI dafür entschieden. was die inet seiten angeht: da musst du wohl für jeden einzelnen chipsatz auf die seite des herstellers gehen. es gibt sicherlich auch specifs, wo alle in einem sind, aber da hab ich gerade keine seite zur hand

    cu todo



  • Ich will erst mal eine routine für meine Grafikkarte schreiben.
    Ob ich dann für weitere Karten eine schreibe werde ich dann ja sehen.

    Ich dachte bei VESA handelt es sich um einen Hardwarestandard, der die Hardware der SVGA Karten bzw. Modi festlegt.
    So wie du das jetzt geschrieben hast, hört sich das ja eher nach einem Softwarestandard aus. Ich möchte aber eher was über Hardwarestands wissen.



  • Moin, Moin...

    Soweit ich weiß, gibt es keine Hardwarestandards im Grafikkartenbereich. Genau das war ja auch das Problem. Jeder Hersteller kochte sein eigenes Süppchen und die Programmierer mussten zusehen, wie sie ihre Programme mit den unterschiedlichen Grafikkarten zur Zusammenarbeit bewegen konnten. Genau hier setzt der VESA-Standard an. Die Hersteller einigten sich auf standartisierte Funktionen und standartisierte Auflösungen. Die Technik bzw. Hardware, die sich jedoch dahinter verbirgt, kann unterschiedlich sein. Du musst Dich also mit der Technik Deiner speziellen Grafikkarte auseinandersetzen, wenn Du sie tatsächlich auf Hardwareebene programmieren möchtest.

    Ciao...



  • Original erstellt von Kal El:**
    Soweit ich weiß, gibt es keine Hardwarestandards im Grafikkartenbereich.**

    Also zumindest VGA ist AFAIK noch direkt eine Hardwareimplementation und ein Standard ists auch 😉
    Mit VGA-Grafik laesst sich nur leider nicht allzuviel anfangen.

    Wenn du direkt die Hardware deiner Grafikkarte programmieren willst, gibt es 2 Moeglichkeiten:
    Entwerder du gehst auf die Homepage deines Grafikchip-Herstellers, der dann uU. keine Dokumentationen kostenlos verteilt oder du disassemblierst dein Grafikkarten-BIOS. (Im VESA-Teil wird ja schliesslich auch direkt mit der Hardware kommuniziert um die ganzen Grafikmodi einzuschalten etc.)

    [ Dieser Beitrag wurde am 01.06.2003 um 12:13 Uhr von Nobuo T editiert. ]



  • Kal El, habe schon beim Hersteller meiner Grafikkarte nachgefragt. Der antwortet aber leider nicht.

    Nobuo T, auf der Homepage des Grafikkartenherstellers findet sich leider nur spärliche Dokumentation. Und über die Programmierung der Karte sowieso gar keine. Wie könnte man das BIOS auslesen? Kennst du gute Diassembler?

    Vielleicht finde ich ja was gutes über das BIOS.
    Ich such dann gleich mal...



  • BIOS Auslesen geht IMHO mit dem Turbo Debugger von Borland ziemlich gut.
    Mit dem kannst du im RM an jede beliebige Stelle im Speicher springen.
    So kannst du entweder den int 10h handler zerlegen oder dir direkt den Entry-point zum VESA-BIOS holen und den dann einzeln zerbasteln. 🙂 (Dafuer waere vielleicht ein etwas intensiverer Blick in ein VESA-Tutorial ganz hilfreich, um die Funktionsnummern richtig verfolgen zu koennen)



  • BIOS Auslesen geht IMHO mit dem Turbo Debugger von Borland ziemlich gut.
    IMHO ist was genau?
    Mit dem kannst du im RM an jede beliebige Stelle im Speicher springen.
    RM - welcher modus? Und wie kommt man da rein?
    So kannst du entweder den int 10h handler zerlegen oder dir direkt den Entry-
    Wie liest man den handler?
    point zum VESA-BIOS holen und den dann einzeln zerbasteln. (Dafuer waere
    Gibt es evtl. dokumentationen über die entry point des VESA-BIOS?
    vielleicht ein etwas intensiverer Blick in ein VESA-Tutorial ganz hilfreich,
    Wo gibt es solche Tutorials günstig?
    Ich möchte nicht unbedingt die ganze Reihe der Dokumente der www.vesa.org kaufen.
    um die Funktionsnummern richtig verfolgen zu koennen)



  • IMHO ist was genau?
    =>Diese Abkuerzungen sollte man eigentlich kennen, wenn man im INet unterwegs ist. url: http://solidworks.cad.de/dfue_tok.htm
    RM - welcher modus?
    RM steht fuer RealMode - das ist ein Prozessormodus, in dem die CPU den Speicher wie ein (1)86 Addressiert (Fuer Abwaertskompatibilitaet)
    Und wie kommt man da rein?
    Starte einfach den TD und du bist praktisch in einem simulierten RM.
    Wie liest man den handler?
    Erstmal Addresse besorgen:
    Entweder ueber die entspechende DOS-Funktion int 21h;ah=25h (nachzulesen in Ralf Browns Interrupt Liste; url: http://www.ctyme.com/intr/int.htm oder Speicher bei 0000:0040 auslesen. (1.word Offset 2.word Segment zum Handler)
    An dieser Addresse wird nun aber vermutlich nicht der gesamte Handler stehen, sondern nur ein kleiner Teil. Du muesstest nun schon dem Code mit dem TD zur entsprechenden Funktion folgen, die du disassemblieren willst.
    Gibt es evtl. dokumentationen über die entry point des VESA-BIOS?/
    Wo gibt es solche Tutorials günstig?
    Ich möchte nicht unbedingt die ganze Reihe der Dokumente der www.vesa.org kaufen.

    Man, man, man 😃 Hier: url: http://www.vesa.org/vbelink.html Voellig kostenlos und sogar direkt von der Quelle. 😉
    Ist nur leider etwas laenger als 2 Zeilen. 🙄

    edit: Sry, irgendwie sind hier ab und an die Links verschwunden, deshalb stehen jetzt alle ausgeschrieben da.

    [ Dieser Beitrag wurde am 09.06.2003 um 18:29 Uhr von Nobuo T editiert. ]



  • Danke für deine Tipps, Nobuo T!
    Werden mich dann mal dran machen, den Code zu entschluesseln, wenn ich mal etwas Zeit habe.
    Vielleicht hat derweilen jemand einen fertigen und evtl. sogar besseren Zeichencode für Punkte im SVGA-modus???



  • TADA, da bin ich!

    ich habe früher auch mal die karten per assembler und direktem hardwarezugriff programmiert. aber das macht keinen sinn. denn mit dem veso bios hat man alles was man braucht. das vesabios bietet zwar keine "echte hardwareprogrammierung" an, aber das spielt für die performance keine rolle. mit dem vesabios kannst du alle notwendigen daten der grafikarten ermitteln und dann auf sie zugreifen. grunsätzlich muss man sich zuerst einen zeiger auf den "flat-screen" speicher holen, in dem das bild (grafikspeicher) linear dargestellt wird. das funktioniert aber nur, wenn du eine karte hast die das kann. allerdings sollte das jede "moderne" karte 100% unterstützen. ich hatte damls eine superschlechte noname und die konnte das auch...

    wenn du dann den zeiger auf den videospeicher hast, dann kannst du da einfach linear reinschreiben. ich habe das damals immer mit einem backpuffer gemacht, da ich meine engine als 3d-engine benutzt habe und nicht als 2d-engine (also als gui-engine oder so).

    ein problem ist noch, das das ganze nur funktioniert, wenn sich die cpu im protected mode befindest (klar...) denn im realmode hast man nur 64k segmente und da ist nix mit linearem speicherzugriff von 4 mbyte oder so :). man braucht dann noch ein DPMI (DosProtectedModeInterface) um an realmode speicher ranzukommen (braucht das vesabios) und das macht das alles noch etwas komplizierter. falls du dich damit nicht auskennst, dann besorg dir ersteinmal informationen über DPMI.

    hier mal ein bischen code aus meiner alten "engine" 🙂

    so in der form nicht wirklich lauffähig, da noch andere teile und der dazugehörige c code fehlt, aber du siehst alles was mann braucht um eine minimalversion zum laufen zu bringen.

    .data
    
    extrn screen   :dword    ;zeiger auf virtuelles vram
    extrn screen_x :dword    ;breite des vram
    extrn screen_y :dword    ;höhe des vram
    
    extrn freemem  :dword    ;freier protected mode speicher
    
    blockh         dd 0
    rmi            db 50 dup (0)
    rms_sel        dw 0
    rms_seg        dw 0
    flatscreen     dd 0
    h_sel          dw 0
    h_off          dd 0
    sliste         dd 2048 dup (0)   ;1024 speicherblöcke
    mliste         db 48 dup (0)     ;speicherinformationen
    
    .code
    
    public init_watcom
    init_watcom proc near
      mov ax,0501h                ;dpmi-function 501h (getmem)
      mov bx,60h                  ;6 MB = 600000h
      mov cx,0000h
      int 31h
      mov word ptr screen+2,bx
      mov word ptr screen,cx
      mov word ptr blockh+2,si
      mov word ptr blockh,di
      mov ax,100h                 ;reserviere realmode-speicher
      mov bx,20h                  ;für den vesamodusinfopuffer
      int 31h
      mov rms_seg,ax
      mov rms_sel,dx
      mov ax,013h                 ;aktiviere Grafikmodus
      int 10h
    
      mov eax,0                   ;lösche speicherliste
      mov ecx,2048
      mov edi,offset sliste  
      rep stosd
      mov ax,500h                 ;ermittle freien speicher
      mov edi,offset mliste
      int 31h
      mov eax,dword ptr mliste[0]
      mov freemem,eax
    
      ret
    init_watcom endp
    
    public close_watcom
    close_watcom proc near
      mov ax,0502h                     ;dpmi-function 502h (freemem)
      mov si,word ptr blockh+2
      mov di,word ptr blockh 
      int 31h
      mov ax,101h                      ;realmode-speicher freigeben
      mov dx,rms_sel
      int 31h
      mov ax,03h                       ;aktiviere Textmodus
      int 10h  
    
      mov edx,0                        ;lösche alle speicherblöcke
    @@ch_lp:
      cmp dword ptr sliste[edx],0
      je @@ch_weiter
      mov ax,0502h                     ;dpmi-function 502h (freemem)
      mov si,word ptr sliste[edx+6]
      mov di,word ptr sliste[edx+4]
      int 31h
    @@ch_weiter:
      add edx,8
      cmp edx,1024*8
      jne @@ch_lp
    
      ret
    close_watcom endp
    
    public svga_modus
    svga_modus proc near
      push ebp
      mov ebp,esp
      push es
    
      cmp dword ptr [ebp+8],0
      jne @@sm_320_240
      mov ax,04f02h
      mov bx,0c136h
      int 10h ;vesabios funktion zum setzen eines grafikmodus
              ;das kann man natürlich auch mit ports und direkter
              ;hardwareporgrammierung machen, aber das bringt keine vorteile
      mov screen_x,320
      mov screen_y,240
      mov eax,136h
      jmp @@sm_initneuermodus
    @@sm_320_240:
    
      cmp dword ptr [ebp+8],1
      jne @@sm_640_480
      mov ax,04f02h
      mov bx,0c112h
      int 10h
      mov screen_x,640
      mov screen_y,480
      mov eax,112h
      jmp @@sm_initneuermodus
    @@sm_640_480:
    
      cmp dword ptr [ebp+8],2
      jne @@sm_800_600
      mov ax,04f02h
      mov bx,0c115h
      int 10h
      mov screen_x,800
      mov screen_y,600
      mov eax,115h
      jmp @@sm_initneuermodus
    @@sm_800_600:
    
      cmp dword ptr [ebp+8],3
      jne @@sm_1024_768
      mov ax,04f02h
      mov bx,0c118h
      int 10h
      mov screen_x,1024
      mov screen_y,768
      mov eax,118h
      jmp @@sm_initneuermodus
    @@sm_1024_768:
    
      jmp @@sm_ende
    @@sm_initneuermodus:
      mov dword ptr rmi[24],eax
      mov dword ptr rmi[28],4f01h
      mov ax,rms_seg
      mov word ptr rmi[34],ax
      mov dword ptr rmi[0],0
      mov dword ptr rmi[20],0
    
      mov ax,300h
      mov bx,10h
      mov cx,0
      mov dx,seg rmi
      mov es,dx
      mov edi,offSET rmi
      int 31h  
    
      mov ax,rms_sel          ;lade flatscreen
      mov es,ax
      mov ebx,es:40           ;steht im modusinfopuffer an offset 40
      mov ecx,ebx
      shr ebx,16
      mov di,0000
      mov si,60
      mov ax,0800h
      int 31h
      shl ebx,16
      mov bx,cx
      mov flatscreen,ebx
    
      mov ecx,0
      mov edx,screen_x
      shl edx,1
      dec edx
      mov ax,7
      int 33h
      mov ecx,0
      mov edx,screen_y
      dec edx
      mov ax,8
      int 33h
    
    @@sm_ende:
      pop es
      mov esp,ebp
      pop ebp
      ret
    svga_modus endp
    
    //diese funktion könnte man heutzutage, wo es ja sowas wie pentium und mmx gibt optimieren...
    public svga_show
    svga_show proc near
      mov esi,screen        ;lade adresse des grafik-puffer
      mov edi,flatscreen    ;lade adresse des linear-frame-buffer
      mov ecx,screen_x      ;berechne anzahl der pixel
      imul ecx,screen_y
      rep movsd
    
      ret
    svga_show endp
    
    public get_mem
    get_mem proc near
      push ebp
      mov ebp,esp
    
      mov edx,0
    
    @@gm_lp:
      mov eax,dword ptr sliste[edx]
      cmp eax,0
      jne @@gm_weiter
    
      mov ax,0501h                       ;dpmi-function 501h (getmem)
      mov bx,[ebp+14]
      mov cx,[ebp+12]
      int 31h
      mov eax,[ebp+8]                    ;lade adresse des zeiger auf speicherbereich
      mov [eax+2],bx                     ;schreibe adresse in zeiger (zeiger auf neuen speicher)
      mov [eax],cx
      mov dword ptr sliste[edx],eax      ;sichere zeiger
      mov word ptr sliste[edx+6],si      ;sichere handle des speicherblocks
      mov word ptr sliste[edx+4],di
      jmp @@gm_ende
    
    @@gm_weiter:
      add edx,8
      cmp edx,1024*8
      jne @@gm_lp
    
    @@gm_ende:
      mov esp,ebp
      pop ebp
      ret
    get_mem endp
    
    public free_mem
    free_mem proc near
      push ebp
      mov ebp,esp
    
      mov edx,0
    
    @@fm_lp:
      mov eax,dword ptr sliste[edx]
      cmp eax,[ebp+8]
      jne @@fm_weiter
    
      mov ax,0502h                     ;dpmi-function 502h (freemem)
      mov si,word ptr sliste[edx+6]
      mov di,word ptr sliste[edx+4]
      int 31h
      mov dword ptr sliste[edx],0      ;lösche listeneintrag
      mov dword ptr sliste[edx+4],0    ;lösche handle
      jmp @@fm_ende
    
    @@fm_weiter:
      add edx,8
      cmp edx,1024*8
      jne @@fm_lp
    
    @@fm_ende:
      mov esp,ebp
      pop ebp
      ret
    free_mem endp
    
    bischen c code
    
    void *screen;                          //virtuelles grafikram//
    long screen_x;                         //breite//
    long screen_y;                         //höhe//
    
    long freemem;                          //freier speicher//
    
    extern void init_watcom(void);
    extern void close_watcom(void);
    
    extern void svga_modus(long modvar);
    extern void svga_show(void);
    
    extern void get_mem(void *zeiger, long size);
    extern void free_mem(void *zeiger);
    

    aber...

    ehrlich gesagt würde ich diesen "mist" nicht mehr machen, da es einfach viel zu viel arbeit ist und man besser mit directx oder opengl DAS macht was man eigentlich möchte... grafik programmieren

    man kann zwar mit dem vesa bios recht gut und sogar sehr schnell 2d grafik realisieren, aber nicht hardwareunterstützt. und 3d grafik erst recht nicht. vielleicht gibt es mittlerweile sogar einen vesa standard für 3d grafik, aber der wird dem, was moderne karten an neuen funktionen unterstützen immer hinterherhinken und das meilenweit. ausserdem dürfte es extrem viel arbeit sein 3d-funktionen zum laufen zu bekommen, wenn man diese mit assembler anspricht.

    3d grafik habe ich früher auch alles mit assembler und c realisiert. man lernt abei viel, z.b. wenn man sich selbst eine funktion zum zeichnen eines texturierten und schattierten polygons schreibt, oder sich um die beleuchtung kümmert, aber es ist extrem viel aufwand.

    ich benutze seit ca. 2 jahren directx und bin glücklich mit meinen 500 fps mit einer 1280x1024er auflösung bei 32bit und geiler 3d-grafik...


Anmelden zum Antworten