Na FreeHostingu Endora běžà desĂtky tisĂc webĹŻ. PĹ™idejte se ještÄ› dnes!
VytvoĹ™it web zdarmaNa FreeHostingu Endora běžà desĂtky tisĂc webĹŻ. PĹ™idejte se ještÄ› dnes!
Vytvořit web zdarmaMOV AX,4f02h MOV BX,videorezim INT 10h
Program VESAdemo; Function NajdiVESArezim(xroz,yroz,bitu:word):word; Function TestMode(videomod,xroz,yroz:word;bitu:byte):boolean; { otestuje, zda ma Videomod pozadovane rozliseni a barevnou hloubku } var buffer:array[0..511] of byte; vysledek:byte; p:pointer; begin p:=@buffer; asmpush es push di mov ax,4f01h mov cx,videomod { naseho kandidata dame do CX } mov es,word ptr p[2] { vygenerovanou tabulku umisti na } mov di,word ptr p[0] { tuto adresu } int 10h mov ax,es:[di] test ax,8 { otestuje, zda je to rezim graficky, ci textovy } jz @chyba @graficky_rezim: mov ax,es:[di+12h] { souhlasi sirka? } cmp ax,xroz jnz @chyba mov ax,es:[di+14h] { souhlasi vyska? } cmp ax,yroz jnz @chyba mov al,es:[di+19h] { souhlasi bitova hloubka? } cmp al,bitu jnz @chyba mov ax,1 { Kandidat vyhovuje? } jmp @konec { skok na konec } @chyba: { Takze smula, kandidat neprosel } xor ax,ax @konec: pop di pop es mov vysledek,alend; Testmode:=vysledek<>0; { Zkraceny zapis. Ekvivalentni zapisu if vysledek=0 then Testmode:=false else Testmode:=true } end; var zakladni_info:array[0..511] of byte; p:pointer; tabulka_videomodu:^word; begin p:=@zakladni_info; asmpush es push di mov ax,4f00h mov es,word ptr p[2] mov di,word ptr p[0] int 10h { nactem zakladni informace o videokarte } db 66h;mov ax,es:[di+0eh] db 66h;mov tabulka_videomodu.word,ax { vytahneme z ni ukazatel na seznam videomodu } pop di pop esend; {Promenna Tabulka_Videomodu ukazuje na seznam vsech dostupnych rezimu VESA} while tabulka_videomodu^<>$0FFFF do { seznam videomodu je ukoncen hodnotou FFFFh } begin if TestMode(tabulka_videomodu^,xroz,yroz,bitu) then { Otestuj rezim } begin NajdiVESArezim:=tabulka_videomodu^; { Vyborne, nasli jsme ho! } Exit; end; inc(tabulka_videomodu); end; NajdiVESArezim:=0; end; Procedure NastavRezim(rezim:word);assembler; asmmov ax,4f02h mov bx,rezim int 10hend; Procedure Zpatky;assembler; asm mov ax,3 int 10hend; var rezim:word; sirka,vyska,hloubka:word; begin writeln('Zadej sirku:');readln(sirka); writeln('Zadej vysku:');readln(vyska); writeln('Zadej bitovou hloubku (pocet bitu na pixel):');readln(hloubka); rezim:=NajdiVESArezim(sirka,vyska,hloubka); if rezim=0 then writeln('Tvoje graficka karta tento rezim nepodporuje.') else NastavRezim(rezim); { A jsme tam ! } readln; Zpatky; writeln(rezim); end.
Program VESAdemo; uses Go32,Dos; { Ovladani konvencni pameti } var VesaBaseInfo:array[0..511] of byte; VesaModeInfo:array[0..255] of byte; PROCEDURE ReadVesaBaseInfos; VAR LowMemPtr : LongInt; Regs:Registers; Begin LowMemPtr:= Global_DOS_Alloc(512); { Alokuj blok konvencni pameti } { Nepouzivame zde totiz rozhrani pro chraneny mod, protoze se nejsme jisti, zda } { ho nase karta podporuje. To totiz zvladaji jenom karty s VESA>=2.0 } { Takze pouzivame realmodove rozhrani a tudiz si musime pripravit blok 512 bajtu v KONVENCNI pameti } FillChar(VesaBaseInfo,SizeOf(VesaBaseInfo),0); VesaBaseInfo[0]:= byte('V'); { Mame VESU 2.0 nebo vyssi? } VesaBaseInfo[1]:= byte('B'); VesaBaseInfo[2]:= byte('E'); VesaBaseInfo[3]:= byte('2'); DOSMemPut(Word(LowMemPtr shr 16),0,VesaBaseInfo,512); {LowMemPtr^:=VesaBaseInfo^} FillChar(Regs,SizeOf(Regs),0); Regs.eax := $4F00; { Zjisti zakladni informace o videokarte } Regs.es := Word(LowMemPtr shr 16); { segment bloku LowMemPtr } Regs.edi := 0; { Je 0. Global_DOS_Alloc to vzdy zaonaci tak, ze offset je 0 } RealIntr($10,Regs); { VesaBaseInfo^:=LowMemPtr^ } DOSMemGet(Word(LowMemPtr shr 16),0,VesaBaseInfo,512); Global_DOS_Free(Word(LowMemPtr)); { Konvencni pamet je vzacny zdroj, } { takze ji uvolnim jak nejdriv to jde } End; PROCEDURE ReadVesaModeInfos(Mode:Word); VAR LowMemPtr : LongInt; Regs:Registers; Begin LowMemPtr:= Global_DOS_Alloc(256); { Alokujem 256 bajtu v konv. pameti } FillChar(VesaModeInfo,SizeOf(VesaModeInfo),0); FillChar(Regs,SizeOf(Regs),0); Regs.es:= Word(LowMemPtr shr 16); Regs.cx:= Mode; Regs.ax:= $4F01; RealIntr($10,Regs); { VesaBaseInfo^:=LowMemPtr^ } DOSMemGet(Word(LowMemPtr shr 16),0,VesaModeInfo,256); Global_DOS_Free(Word(LowMemPtr)); { Konvencni pamet zase uvolnime } End; Function NajdiVESArezim(sirka,vyska,hloubka:word):longint; var segm,ofss,i:word; mode:array[0..255] of word; sv,vv:word; dd:longint; begin ReadVESABaseInfos; Move(VesaBaseInfo[$0e],dd,4); segm := Segment_To_Descriptor(dd shr 16); ofss := dd and $FFFF; seg_move(segm, ofss, get_ds, longint(@mode), SizeOf(mode)); for i:=0 to 255 do if mode[i]=$FFFF then Exit(0) else begin ReadVESAmodeInfos(mode[i]); move(VESAMODEINFO[$12],sv,2); move(VESAMODEINFO[$14],vv,2); if (sv=sirka) and (vv=vyska) and (VESAMODEINFO[$19]=hloubka) then Exit(mode[i]); end; NajdiVESArezim:=0; end; Procedure NastavRezim(rezim:word);assembler; asmmov ax,4f02h mov bx,rezim int 10hend; Procedure Zpatky;assembler; asm mov ax,3; int 10h; end; var rezim:word; sirka,vyska,hloubka:word; begin writeln('Zadej sirku:');readln(sirka); writeln('Zadej vysku:');readln(vyska); writeln('Zadej bitovou hloubku (pocet bitu na pixel):');readln(hloubka); rezim:=NajdiVESArezim(sirka,vyska,hloubka); if rezim=0 then writeln('Tvoje graficka karta tento rezim nepodporuje.') else NastavRezim(rezim); { A jsme tam ! } readln; Zpatky; writeln(rezim); end.
repeat For y:=o to MaxY do For x:=0 to MaxX do NechToChviliPusobit(cas); until Vypnuti_pocitace; { Jde to vypnout i programove, ale to nas ted nezajima }Z uvedeneho vyplývá následující: paprsek vždy putuje jedním směrem.
Program refresh; {$Q-} {$IFDEF FPC} {$ASMMODE INTEL} uses Go32,Dos; {$ENDIF} const HNEG = 1 shl 2; VNEG = 1 shl 3; type CRTC_info=packed record HorizontalTotal:word; HorizontalSyncStart:word; HorizontalSyncEnd:word; VerticalTotal:word; VerticalSyncStart:word; VerticalSyncEnd:word; Flags:byte; PixelClock:longint; { v Hz } RefreshRate:word; { v setinach Hz } reserved:array[0..39] of byte; end; {$IFNDEF FPC}dword = longint;{$ENDIF} Procedure Vypocitej_crct_casovani(xres,yres,xadjust,yadjust:longint;var crtc:CRTC_info); { Nema smysl snazit se tohle pochopit. Proste to tak je. } { Akorat jenom: To divne nasobeni desetinnymi cisly je proto, ze skutecna } { sirka obrazovky je rekneme o par procent vetsi nez udavane rozliseni, } { protoze kolem zobrazovaci plochy zustava uzke nezobrazovaci okoli. } var HTotal, VTotal:longint; HDisp, VDisp:longint; HSS, VSS:longint; HSE, VSE:longint; HSWidth, VSWidth:longint; SS, SE:longint; doublescan:boolean; begin doublescan:=false; if (yres < 400) then begin doublescan := TRUE; yres :=yres*2; end; HDisp := xres; Htotal:=round(HDisp*1.27) and (not 7); HSWidth := round((HTotal - HDisp) / 5) and (not 7); HSS := HDisp + 16; HSE := HSS + HSWidth; VDisp := yres; VTotal := round(VDisp * 1.07); VSWidth := round(VTotal / 100) + 1; VSS := VDisp + round((VTotal - VDisp) / 5) + 1; VSE := VSS + VSWidth; SS := HSS + xadjust; SE := HSE + xadjust; if (xadjust < 0) then if SS < HDisp + 8 then begin SS := HDisp + 8; SE := SS + HSWidth; end else else if HTotal - 24 < SE then begin SE := HTotal - 24; SS := SE - HSWidth; end; HSS := SS; HSE := SE; SS := VSS + yadjust; SE := VSE + yadjust; if (yadjust < 0) then if SS < VDisp + 3 then begin SS := VDisp + 3; SE := SS + VSWidth; end else else if VTotal - 4 < SE then begin SE := VTotal - 4; SS := SE - VSWidth; end; VSS := SS; VSE := SE; crtc.HorizontalTotal := HTotal; crtc.HorizontalSyncStart := HSS; crtc.HorizontalSyncEnd := HSE; crtc.VerticalTotal := VTotal; crtc.VerticalSyncStart := VSS; crtc.VerticalSyncEnd := VSE; crtc.Flags := HNEG or VNEG; if doublescan then crtc.flags:=crtc.flags or byte(doublescan); end; Function get_closest_pixel_clock(mode_no:word;vclk:longint):dword; { Pixel clock urcuje, jak dlouho se ma paprsek zdrzet na miste nez prejde na dalsi pozici } { Sice jsme to uz vypocitali v procedure Vypocitej_CRTC_casovani, ale jde o to, } { ze graficky cip nemuze generovat uplne jakoukoliv hodnotu "pixel clock". } { Nastesti umi rict, jaky umi vygenerovat nejpodobnejsi } {$IFDEF FPC} var r:registers; begin r.ax:=$4f0B; r.bl:=0; r.ecx:=vclk; r.dx:=mode_no; intr($10,r); if r.ah<>0 then get_closest_pixel_clock:=0 else get_closest_pixel_clock:=r.ecx; {$ELSE} var l:longint; begin asmmov ax,4f0bh xor bl,bl db 66h;mov cx,vclk.word mov dx,mode_no int 10h cmp ah,0 jnz @preskoc db 66h; xor cx,cx @preskoc: db 66h; mov l.word,cx end; get_closest_pixel_clock:=l; {$ENDIF} end; Function VESA_version_3_available:boolean; { Nechce se mi s tim patlat. Zjistuje se to z funkce 4f00h } begin VESA_version_3_available:=true; end; Function Najdi_Videorezim(xr,yr,bpp:longint):word; { Nechce se mi s tim patlat. } begin Najdi_Videorezim:=$103+$4000; end; Procedure Nastav_grafiku(xr,yr,bpp,frek:longint); var xadjust,yadjust:longint; crtc:CRTC_info; vclk,c,long:dword; mode,w:word; segm,ofsm:word; f0:double; {$IFDEF FPC}regs:Registers;{$ENDIF} begin xadjust:=0; { jemne horizontalni } yadjust:=0; { a vertikalni centrovani obrazu } mode:=Najdi_Videorezim(xr,yr,bpp); if VESA_version_3_available then begin Vypocitej_crct_casovani(xr,yr,xadjust,yadjust,crtc); vclk := dword(crtc.HorizontalTotal * crtc.VerticalTotal * frek); vclk := get_closest_pixel_clock(mode, vclk); end else vclk:=0; if (vclk <> 0) then begin f0 := vclk / (crtc.HorizontalTotal * crtc.VerticalTotal); c:=round(f0+0.5); crtc.PixelClock := vclk; crtc.RefreshRate := frek * 100; {$IFDEF FPC} long:=Global_DOS_alloc(sizeOf(CRTC_info)); w:=Hi(long); dosmemput(w,0,crtc, sizeof(CRTC_info)); Regs.eax:=$4F02; Regs.di := 0; Regs.es := w; Regs.ebx:=mode or $0800; RealIntr($10, Regs); Global_DOS_free(Lo(long)); {$ELSE} segm:=seg(crtc); ofsm:=ofs(crtc); asmpush es;push si mov ax,4f02h mov bx,segm mov es,bx mov di,ofsm mov bx,mode or mode,800h int 10h pop si; pop es end; {$ENDIF} end else begin { Muzeme nechat spolecne pro TP i FP } asm mov ax,4f02h mov bx,mode int 10h end; end; end; Procedure Test; begin {$IFDEF FPC} OutPortb($3C8,0); OutPortb($3C9,63); OutPortb($3C9,63); OutPortb($3C9,63); {$ELSE} Port[$3C8]:=0; Port[$3C9]:=63; Port[$3C9]:=63; Port[$3C9]:=63; {$ENDIF} readln; end; Procedure Zpatky;assembler; asm mov ax,3; int 10h; end; var sirka,vyska:longint; begin writeln('Napred zkusime nastavit 800x600 8bit na 55Hz');readln; sirka:=800; vyska:=600; Nastav_grafiku(sirka,vyska,8,0); { sirka, vyska, bpp, frekvence } Test; Zpatky; writeln('Ted 800x600 8bit na 100Hz. Je to lepsi?');readln; Nastav_grafiku(sirka,vyska,8,100); { sirka, vyska, bpp, frekvence } Test; Zpatky; end.