flat assembler
Message board for the users of flat assembler.

Index > OS Construction > What are the ways to create GUI

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Rusik wrote:
freecrac I do not dispute that the native resolution of LCD-monitors provides the best quality, but VESA does not support modes what are not defined by this standard. Sad
It would be nice if it was possible to use any modes with any resolution using LFB or something else for example...

So, if I have a monitor with 1600x900 resolution, what mode from the list available to be most optimal for me? That's what I would like to know.

And more, maybe it's not this topic, but what about the Menuet64. From the above I assume that this OS has a 64-bit kernel but uses 16 or 32-bits VESA interface, constantly switching in (un)real mode(if it works in Protected Mode of course).


If you chose for example 800x600 24/32bpp it will still fit your screen in most cases.
You may need to reset the monitor by using the buttons on the monitor.
For X and Y.

Also you need to give more info, not it does not work.

How have you tryed to boot.
Did you use real PC or emulator.
When run what happened, crash, error mesage, black screen, half filled screen.

Also do not jump down coders throats, because you do not like there advice.
That only works when your giving advice Wink
As no one's getting paid to help you.
Post 16 May 2012, 13:45
View user's profile Send private message Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
Dex4u I am not in any way want to sound ungrateful. I'm glad any useful information. Of course I understand that responses to the forum and no one pays it's just an expression of desire to help and if I had enough knowledge I'd helped to also. But I would not in any way to cast "What are you doing here if you do not know...". Confused Confused Confused

You also wrote "Also you need to give more info, not it does not work". You mean your code?
Code:
;************************************ 
; By Dex 
; Assemble with fasm  
; c:\fasm Vesa.asm Vesa.bin 
; 
;************************************ 
org 0x7C00  

use16 
;**************************** 
; Realmode startup code. 
;**************************** 

start: 
        xor   ax,ax 
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   sp,0x7C00  

;**************************** 
; Vesa start code. 
;**************************** 

        mov  bx,4112h 
        mov  ax,4f01h 
        mov  di,Mode_Info        
        mov  cx,bx 
        int  10h  
         
        mov  ax,4f02h 
        int  10h 

;***************************** 
; Setting up, to enter pmode. 
;***************************** 

        cli  
        lgdt  [gdtr] 
         
        mov   eax, cr0 
        or    al,0x1  
        mov   cr0,eax 
  
        jmp   0x10: protected 

;***************************** 
; Pmode.  
;***************************** 

use32 
protected: 
        mov   ax,0x8  
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   esp,0x7C00 
;***************************** 
; Turn floppy off. 
;***************************** 

        mov   dx,3F2h 
        mov   al,0 
        out   dx,al 

;***************************** 
; Do we have 32 BitsPerPixel. 
;***************************** 

        cmp   byte[ModeInfo_BitsPerPixel],32 
        jne   Letsloop  

;***************************** 
; fade background screen. 
;***************************** 

fade_screen: 
        mov   edx,[ModeInfo_PhysBasePtr] 
        mov   edi,edx 
        xor   eax,eax 
        mov   al,0xc5           
        xor   ebx,ebx 
        mov   bl,195  
DoLoop:     
        mov   cx,640*2  
        dec   eax     

        rep   stosd 
        
        dec   ebx 
        jnz   DoLoop 
Letsloop: 
        hlt 
        jmp   Letsloop 

;************************************* 
; GDT.  
;************************************* 

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000 
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF 
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF 
gdt_end: 

gdtr:       dw gdt_end - gdt - 1                                           
            dd gdt  


;************************************* 
; Make program 510 byte's + 0xaa55 
;************************************* 
             
times 510- ($-start)  db 0   
dw 0xaa55 

;************************************* 
; Put uninitialized data here. 
;************************************* 

;=========================================================; 
; Vesa Information Block                         11/12/03 ; 
;---------------------------------------------------------; 
; DOS EXTREME OS V0.01                                    ; 
; by Craig Bamford(Dex).                                  ; 
;                                                         ; 
;=========================================================; 

;============================== VESA MODE INFORMATION =========================================== 
Mode_Info:               
ModeInfo_ModeAttributes         rw      1 
ModeInfo_WinAAttributes         rb      1 
ModeInfo_WinBAttributes         rb      1 
ModeInfo_WinGranularity         rw      1 
ModeInfo_WinSize                rw      1 
ModeInfo_WinASegment            rw      1 
ModeInfo_WinBSegment            rw      1 
ModeInfo_WinFuncPtr             rd      1 
ModeInfo_BytesPerScanLine       rw      1 
ModeInfo_XResolution            rw      1 
ModeInfo_YResolution            rw      1 
ModeInfo_XCharSize              rb      1 
ModeInfo_YCharSize              rb      1 
ModeInfo_NumberOfPlanes         rb      1 
ModeInfo_BitsPerPixel           rb      1 
ModeInfo_NumberOfBanks          rb      1 
ModeInfo_MemoryModel            rb      1 
ModeInfo_BankSize               rb      1 
ModeInfo_NumberOfImagePages     rb      1 
ModeInfo_Reserved_page          rb      1 
ModeInfo_RedMaskSize            rb      1 
ModeInfo_RedMaskPos             rb      1 
ModeInfo_GreenMaskSize          rb      1 
ModeInfo_GreenMaskPos           rb      1 
ModeInfo_BlueMaskSize           rb      1 
ModeInfo_BlueMaskPos            rb      1 
ModeInfo_ReservedMaskSize       rb      1 
ModeInfo_ReservedMaskPos        rb      1 
ModeInfo_DirectColorModeInfo    rb      1 
; VBE 2.0 extensions 
ModeInfo_PhysBasePtr            rd      1 
ModeInfo_OffScreenMemOffset     rd      1 
ModeInfo_OffScreenMemSize       rw      1 

;======================================= START OF PROGRAM  ======================================
    

Yes, it does not work on my computer but I have some excellent examples of working.

I use real PC, write *.bin file in boot sector of my USB flash and load from it. When I run your code I see that BIOS read boot sector successfully, but then I see only black screen and a text cursor. Crying or Very sad

Also the topic, I think 1280x1024 mode is best for me because it's closest to 1600x900. So I think that the mode with highest resolution provides the best quality. I mistaken? Question
Post 16 May 2012, 14:24
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac
Rusik wrote:
freecrac I do not dispute that the native resolution of LCD-monitors provides the best quality, but VESA does not support modes what are not defined by this standard. Sad

The VESA organisation itself does not support any vesa modes since VBE2, not the older vesa standard modes and also not any newer modes!
But the card manufactures can implement also new vesa modes inside of their vesa-bios.

vbe3.pdf
Quote:
Starting with VBE version 2.0, VESA will no longer define new VESA mode numbers and it will no longer be mandatory to support these old mode numbers. OEM's who wish to add new VBE mode numbers to their implementations, must make sure that all new modes are defined with mode numbers above 0x100, However, it is highly recommended that BIOS implementations continue to support these mode numbers for compatibility with older software and add new mode numbers after the last VESA defined mode number.

Quote:
It would be nice if it was possible to use any modes with any resolution using LFB or something else for example...

Yes it would be nice, but we can only use the vesa modes that comes with the vesa bios of our card manufacturer. (And older vesa driver for DOS are only for very old card without any vesa bios.)
Next problem, we can not know wich card provide what sort of resolutions and modes. There are no informations for modern cards about vesa modes from the manufacturer.
(i had no luck to find a modelist inside of a bios when looking at tables and inside of the bios-code without to call the vesa function. The same problem with bios image files that we can download.)
So i only can hope that more vesa programmers share their modelist and resolutions what they are found on their cards.
Quote:
So, if I have a monitor with 1600x900 resolution, what mode from the list available to be most optimal for me? That's what I would like to know.

The best tip that i can give you is to make a test with diffent modes and you will see whats happend. I would boot a MSDOS 7.1 from my DOS Boot-CD or from my 2GB-USB-Stick, or any other DOS to test it.

Here is a little DOS-programm (written for MASM and a 80386+) that prints the modelist of a VBE2-bios to the text-screen. (Sorry for the comments only in the german language.)
Code:
.MODEL SMALL                          ; Programm möglichst klein halten
.386
  CODE SEGMENT use16 'CODE'
 assume cs:CODE,ds:DATEN,ss:STAPEL
 org 100h
START:    mov      ax, DATEN           ; Segmentadresse vom Datenbereich
   mov      ds, ax              ;  in das DS-Segmentregister laden
     mov      es, ax              ;  in das ES-Segmentregister laden
     mov      di, OFFSET VINF     ; OFFSET für ausgewählten Datenbereich (512 Bytes)
   mov      ax, 4F00h           ; Vesa Funktionsnummer 0 Vesa-Bios-Info
        int 10h                      ;  holt 512 Bytes nach es:di (Datensegment:VINF)
       cmp      ax, 4Fh             ; Wenn Rückgabewert "4F", dann war Funktion erfolgreich
     jnz NOVESA                   ;  sonst FEHLER: Kein Vesabios vorhanden

       mov      dl, [di+5]          ; Major version number of Vesa über ds:di+5 in das dl-Register holen
      cmp      dl, 2               ;  kleiner als Version 2 ?
     jb  VESA1                    ;  wenn ja FEHLER: Keine Modeliste vorhanden.

          mov      dx, OFFSET HEADER
          mov      ah, 9
          int 21h

     lfs      si, [di+0Eh]        ; Pointer der Modeliste über ds:di+E ins fs-Segmentregister und si-Offsetregister laden

MODE:     mov      cx, fs:[si]         ; Modenummern über fs:si ins cx-register holen
         add      si, 2               ; Qell-Adresszeiger(Offset) erhöhen
   cmp      cx, 0FFFFh          ;  Ende der Liste erreicht?
    jz  MEND
          
          mov      ax, cx
          call HEXOUT16                ; Modenummer ausgeben

     mov      ax, 4F01h           ; Modus spezifische Info holen
          mov      di, OFFSET MINF
   int 10h                      ; es:di 256 byte
   cmp      ax, 4Fh
    jnz short NOVESA             ; FEHLER: wird nicht unterstützt

      mov      ax, [di+12h]        ; MaxX
          call DEZOUT16

          mov      dx, OFFSET X
          mov      ah, 9
          int 21h

          mov      ax, [di+14h]        ; MaxY
          call DEZOUT16

          mov      dx, OFFSET X
          mov      ah, 9
          int 21h

          xor      ax, ax
     mov      al, [di+19h]        ; Bit per pixel?
          call DEZOUT16

          mov      dx, OFFSET SPACE
          mov      ah, 9
          int 21h

    and      BYTE PTR[di], 80h   ;  linear access enable ?
          jz  short NOLIN
          mov      eax, [di+28h]       ;  linearer Bild-Offset vorhanden ?
          call HEXOUT32

NOLIN:    mov      dx, OFFSET CRLF
          mov      ah, 9
          int 21h
          jmp MODE
;-------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
NOVESA:   mov      dx, OFFSET T1
          mov      ah, 9
          int 21h
          mov      cl, 0FFh
          jmp short ERREND
;-------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
VESA1:    mov      dx, OFFSET T2
          mov      ah, 9
          int 21h
          mov      cl, 1
          jmp short ERREND
;-------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
MEND:     xor      cl, cl
ERREND:   mov      al, cl             ; ERRORLEVEL holen
          mov      ah, 4Ch            ; Rücksprung zu DOS, Programm-Ende
          int 21h
;----------------------------------------------------------------------------
; AX nach fünf dezimalen ASCII's wandeln und im Daten-Bereich ablegen
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
DEZOUT16: pusha
          mov      di, OFFSET DEZ16
          mov      cl, 5              ; fünf dezimale ASCII's
          mov      bx, 10000
WANDEL:   xor      dx, dx
          div      bx
          add      al, 30h            ; nach ASCII wandeln
          mov      si, dx             ; Rest retten
          mov      [di], al           ; Ziffer retten
          inc      di                 ; Zeiger erhöhen
          mov      ax, bx
          mov      bx, 0Ah
          xor      dx, dx
          div      bx
          mov      bx, ax
          mov      ax, si
          dec      cl
          jnz WANDEL
;-------------------------------------
          mov      si, OFFSET DEZ16 -1 ; erste(n) Null(en) überlesen
          mov      dx, si
          inc      dx
NULL:     inc      si
          cmp     BYTE PTR[si], "0"
          jz  NULL
          sub      si, 5
          cmp      si, dx
          jz  short AUSG              ; keine null vorhanden !
          add      si, 5
          mov      dx, si
AUSG:     mov      ah, 9              ; dezimale Zahl ausgeben
          int 21h
          popa
          ret
;----------------------------------------------------------------------------
; EAX nach acht hexadezimale ASCII's wandeln und im Daten-Bereich ablegen
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
HEXOUT32: pusha
          mov      di, OFFSET HEX32   ; Doppel-Word nach Hex-Ziffern wandeln
          mov      cl, 8              ; 8 Ziffern
A:        rol      eax, 4             ; 1 Nibble weiter
          mov      bl, al
          and      bl, 0Fh            ; nur low-Nibble
          add      bl, 30h            ; nach ASCII wandeln
          cmp      bl, 39h            ;  größer als Ziffer neun ?
          jna short B
          add      bl, 7              ; dann Buchstabe von "A" bis "F"
B:        mov      [di], bl           ; ASCII retten
          inc      di                 ; Zeiger erhöhen
          dec      cl                 ; Ziffer-Anzahl verringern
          jnz A
;-------------------------------------
          mov      dx, OFFSET HEX32
          mov      ah, 9              ; hexadezimale Zahl ausgeben
          int 21h
          popa
          ret
;----------------------------------------------------------------------------
; AX nach vier hexadezimale ASCII's wandeln und im Daten-Bereich ablegen
;----------------------------------------------------------------------------
 org START + ((($-START)/16)*16)+16   ; Code-Ausrichtung
;-------------------------------------
HEXOUT16: pusha
          mov      di, OFFSET HEX16   ; Word nach Hex-Ziffern wandeln
          mov      cl, 4              ; 4 Ziffern
C:        rol      ax, 4              ; 1 Nibble weiter
          mov      bl, al
          and      bl, 0Fh            ; nur low-Nibble
          add      bl, 30h            ; nach ASCII wandeln
          cmp      bl, 39h            ;  größer als Ziffer neun ?
          jna short D
          add      bl, 7              ; dann Buchstabe von "A" bis "F"
D:        mov      [di], bl           ; ASCII retten
          inc      di                 ; Zeiger erhöhen
          dec      cl                 ; Ziffer-Anzahl verringern
          jnz C
;-------------------------------------
          mov      dx, OFFSET HEX16
          mov      ah, 9              ; hexadezimale Zahl ausgeben
          int 21h
          popa
          ret
  CODE ends
;----------------------------------------------------------------------------
  DATEN SEGMENT use32 'DATA'
;-------------------------------------
VINF      DB 512 dup (0AAh)            ; Vesa-Info(4F00)
MINF      DB 512 dup (44h)             ; Mode-Info(4F01)
DEZ16     DB "00000","$"
HEX32     DB "00000000 ","$"
HEX16     DB "0000 ","$"
HEADER    DB "Vesamode,XRes,YRes,Bits per Pixel,Adresse des Framebuffer",0Dh,0Ah,"$"
CRLF      DB 0Dh,0Ah,"$"
X         DB "x","$"
SPACE     DB " ","$"
T1        DB "Kein Vesabios vorhanden.", 0Dh, 0Ah, "$"
T2        DB "Keine Modeliste vorhanden.", 0Dh, 0Ah, "$"
  DATEN ends
;----------------------------------------------------------------------------
  STAPEL SEGMENT use16 STACK 'STACK'
       DB 100h dup (88h)
  STAPEL ends
 end
    

Feel free to grab and seperate any part of the code to ask about it, if you can not understand it what the commands exactly do.

Dirk
Post 16 May 2012, 15:53
View user's profile Send private message Send e-mail Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Rusik wrote:
Dex4u I am not in any way want to sound ungrateful. I'm glad any useful information. Of course I understand that responses to the forum and no one pays it's just an expression of desire to help and if I had enough knowledge I'd helped to also. But I would not in any way to cast "What are you doing here if you do not know...". Confused Confused Confused

You also wrote "Also you need to give more info, not it does not work". You mean your code?
Code:
;************************************ 
; By Dex 
; Assemble with fasm  
; c:\fasm Vesa.asm Vesa.bin 
; 
;************************************ 
org 0x7C00  

use16 
;**************************** 
; Realmode startup code. 
;**************************** 

start: 
        xor   ax,ax 
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   sp,0x7C00  

;**************************** 
; Vesa start code. 
;**************************** 

        mov  bx,4112h 
        mov  ax,4f01h 
        mov  di,Mode_Info        
        mov  cx,bx 
        int  10h  
         
        mov  ax,4f02h 
        int  10h 

;***************************** 
; Setting up, to enter pmode. 
;***************************** 

        cli  
        lgdt  [gdtr] 
         
        mov   eax, cr0 
        or    al,0x1  
        mov   cr0,eax 
  
        jmp   0x10: protected 

;***************************** 
; Pmode.  
;***************************** 

use32 
protected: 
        mov   ax,0x8  
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   esp,0x7C00 
;***************************** 
; Turn floppy off. 
;***************************** 

        mov   dx,3F2h 
        mov   al,0 
        out   dx,al 

;***************************** 
; Do we have 32 BitsPerPixel. 
;***************************** 

        cmp   byte[ModeInfo_BitsPerPixel],32 
        jne   Letsloop  

;***************************** 
; fade background screen. 
;***************************** 

fade_screen: 
        mov   edx,[ModeInfo_PhysBasePtr] 
        mov   edi,edx 
        xor   eax,eax 
        mov   al,0xc5           
        xor   ebx,ebx 
        mov   bl,195  
DoLoop:     
        mov   cx,640*2  
        dec   eax     

        rep   stosd 
        
        dec   ebx 
        jnz   DoLoop 
Letsloop: 
        hlt 
        jmp   Letsloop 

;************************************* 
; GDT.  
;************************************* 

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000 
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF 
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF 
gdt_end: 

gdtr:       dw gdt_end - gdt - 1                                           
            dd gdt  


;************************************* 
; Make program 510 byte's + 0xaa55 
;************************************* 
             
times 510- ($-start)  db 0   
dw 0xaa55 

;************************************* 
; Put uninitialized data here. 
;************************************* 

;=========================================================; 
; Vesa Information Block                         11/12/03 ; 
;---------------------------------------------------------; 
; DOS EXTREME OS V0.01                                    ; 
; by Craig Bamford(Dex).                                  ; 
;                                                         ; 
;=========================================================; 

;============================== VESA MODE INFORMATION =========================================== 
Mode_Info:               
ModeInfo_ModeAttributes         rw      1 
ModeInfo_WinAAttributes         rb      1 
ModeInfo_WinBAttributes         rb      1 
ModeInfo_WinGranularity         rw      1 
ModeInfo_WinSize                rw      1 
ModeInfo_WinASegment            rw      1 
ModeInfo_WinBSegment            rw      1 
ModeInfo_WinFuncPtr             rd      1 
ModeInfo_BytesPerScanLine       rw      1 
ModeInfo_XResolution            rw      1 
ModeInfo_YResolution            rw      1 
ModeInfo_XCharSize              rb      1 
ModeInfo_YCharSize              rb      1 
ModeInfo_NumberOfPlanes         rb      1 
ModeInfo_BitsPerPixel           rb      1 
ModeInfo_NumberOfBanks          rb      1 
ModeInfo_MemoryModel            rb      1 
ModeInfo_BankSize               rb      1 
ModeInfo_NumberOfImagePages     rb      1 
ModeInfo_Reserved_page          rb      1 
ModeInfo_RedMaskSize            rb      1 
ModeInfo_RedMaskPos             rb      1 
ModeInfo_GreenMaskSize          rb      1 
ModeInfo_GreenMaskPos           rb      1 
ModeInfo_BlueMaskSize           rb      1 
ModeInfo_BlueMaskPos            rb      1 
ModeInfo_ReservedMaskSize       rb      1 
ModeInfo_ReservedMaskPos        rb      1 
ModeInfo_DirectColorModeInfo    rb      1 
; VBE 2.0 extensions 
ModeInfo_PhysBasePtr            rd      1 
ModeInfo_OffScreenMemOffset     rd      1 
ModeInfo_OffScreenMemSize       rw      1 

;======================================= START OF PROGRAM  ======================================
    

Yes, it does not work on my computer but I have some excellent examples of working.

I use real PC, write *.bin file in boot sector of my USB flash and load from it. When I run your code I see that BIOS read boot sector successfully, but then I see only black screen and a text cursor. Crying or Very sad

Also the topic, I think 1280x1024 mode is best for me because it's closest to 1600x900. So I think that the mode with highest resolution provides the best quality. I mistaken? Question


Ok thats more helpful, first to answer your ?, i would say 1280x1024 mode is not good, because 1 it maybe available on your PC, but its not a common mode.
So your boot loader would not work.

I would say stick with 800x600 its one of the commonest and it will give you good speed.
Just think for example about the size a image would be if its 1280x1024.

Anyway i modded the above code and made a floppy image, can you test it and let me know what it does.

And you need to run a test program to test what modes your card supports.
[EDIT] As freecrac has posted.[/EDIT]


Description:
Download
Filename: vesa.zip
Filesize: 2.04 KB
Downloaded: 146 Time(s)

Post 16 May 2012, 15:58
View user's profile Send private message Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
Dex4u thanks!!! Very Happy Your example work perfect. One question, why you chose *.img format (not *.bin) and can you give me your source code?

You wrote also: '' i would say 1280x1024 mode is not good...''. And what you think about 10Fh: 320x200 (192 Kb only).

freecrac: ... the card manufactures can implement also new vesa modes inside of their vesa-bios.

Can implement but not required.

My ATI Catalyst Driver support 1600x900 mode, but when I get list of all my VESA modes max resolution was 1280x1024. So I need in my code chose max optimal mode (for monitor which is used) supported by all BIOS.
Post 16 May 2012, 16:42
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Rusik wrote:
Dex4u thanks!!! Very Happy Your example work perfect. One question, why you chose *.img format (not *.bin) and can you give me your source code?

You wrote also: '' i would say 1280x1024 mode is not good...''. And what you think about 10Fh: 320x200 (192 Kb only).

freecrac: ... the card manufactures can implement also new vesa modes inside of their vesa-bios.

Can implement but not required.

My ATI Catalyst Driver support 1600x900 mode, but when I get list of all my VESA modes max resolution was 1280x1024. So I need in my code chose max optimal mode (for monitor which is used) supported by all BIOS.


Here is the code
Code:
;************************************ 
; By Dex 
; Assemble with fasm  
; c:\fasm Vesa.asm Vesa.bin 
; 
;************************************ 
org 0x7C00  

use16 
;**************************** 
; Realmode startup code. 
;**************************** 

start: 
        xor   ax,ax 
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   sp,0x7C00  

;**************************** 
; Vesa start code. 
;**************************** 

        mov  bx,4115h ; is the mode number 800x600
        mov  ax,4f01h 
        mov  di,Mode_Info        
        mov  cx,bx 
        int  10h  
         
        mov  ax,4f02h 
        int  10h 

;***************************** 
; Setting up, to enter pmode. 
;***************************** 

        cli  
        lgdt  [gdtr] 
         
        mov   eax, cr0 
        or    al,0x1  
        mov   cr0,eax 
  
        jmp   0x10: protected 

;***************************** 
; Pmode.  
;***************************** 

use32 
protected: 
        mov   ax,0x8  
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   esp,0x7C00 
;***************************** 
; Turn floppy off. 
;***************************** 

        mov   dx,3F2h 
        mov   al,0 
        out   dx,al 

        mov   edi,[ModeInfo_PhysBasePtr]
        mov   eax,0x00ffffff
        mov   ecx,800*600  ; if you change mode change these
        rep   stosd
Letsloop: 
        hlt 
        jmp   Letsloop 

;************************************* 
; GDT.  
;************************************* 

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000 
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF 
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF 
gdt_end: 

gdtr:       dw gdt_end - gdt - 1                                           
            dd gdt  


;************************************* 
; Make program 510 byte's + 0xaa55 
;************************************* 
             
times 510- ($-start)  db 0   
dw 0xaa55 

;************************************* 
; Put uninitialized data here. 
;************************************* 

;=========================================================; 
; Vesa Information Block                         11/12/03 ; 
;---------------------------------------------------------; 
; DOS EXTREME OS V0.01                                    ; 
; by Craig Bamford(Dex).                                  ; 
;                                                         ; 
;=========================================================; 

;============================== VESA MODE INFORMATION =========================================== 
Mode_Info:               
ModeInfo_ModeAttributes         rw      1 
ModeInfo_WinAAttributes         rb      1 
ModeInfo_WinBAttributes         rb      1 
ModeInfo_WinGranularity         rw      1 
ModeInfo_WinSize                rw      1 
ModeInfo_WinASegment            rw      1 
ModeInfo_WinBSegment            rw      1 
ModeInfo_WinFuncPtr             rd      1 
ModeInfo_BytesPerScanLine       rw      1 
ModeInfo_XResolution            rw      1 
ModeInfo_YResolution            rw      1 
ModeInfo_XCharSize              rb      1 
ModeInfo_YCharSize              rb      1 
ModeInfo_NumberOfPlanes         rb      1 
ModeInfo_BitsPerPixel           rb      1 
ModeInfo_NumberOfBanks          rb      1 
ModeInfo_MemoryModel            rb      1 
ModeInfo_BankSize               rb      1 
ModeInfo_NumberOfImagePages     rb      1 
ModeInfo_Reserved_page          rb      1 
ModeInfo_RedMaskSize            rb      1 
ModeInfo_RedMaskPos             rb      1 
ModeInfo_GreenMaskSize          rb      1 
ModeInfo_GreenMaskPos           rb      1 
ModeInfo_BlueMaskSize           rb      1 
ModeInfo_BlueMaskPos            rb      1 
ModeInfo_ReservedMaskSize       rb      1 
ModeInfo_ReservedMaskPos        rb      1 
ModeInfo_DirectColorModeInfo    rb      1 
; VBE 2.0 extensions 
ModeInfo_PhysBasePtr            rd      1 
ModeInfo_OffScreenMemOffset     rd      1 
ModeInfo_OffScreenMemSize       rw      1 

;======================================= START OF PROGRAM  ======================================
    


I just changed the mode number from 4112h (640x480 32bpp) seems your card does not support that mode.
I changed it to 4115h which is 800x600 24/32bpp.

But you will need to enable A20 for higher res.
If you see stripes, than its using 24bits per pixel, if full white its 32bpp.
You can try high res but you need to change both the mode number and the other bit i written comments on.
But you may see black at the bottom of screen as you move up the modes, this is because of A20 needing enabling (emulator seem to enable it).
I made it as a floppy, because i thought that what you wanted.

NOTE: Theres no error checking for available modes (as i written the simplest code, so you can understand how it work).
So you will need to add that yourself.

As for 320x200 it too low res, best to stick with text mode (than 320x200 )
Post 16 May 2012, 17:00
View user's profile Send private message Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
Dex4u you wrote "But you will need to enable A20 for higher res." I just add code for open A20
Code:
;*****************************  
; Setting up, to enter pmode.  
;*****************************  

        cli   
        lgdt  [gdtr]

        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        in   al, 92h            ;Open A20
        or   al, 10b
        out  92h, al
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          
        mov   eax, cr0  
        or    al,0x1   
        mov   cr0,eax  
   
        jmp   0x10: protected  

;*****************************  
; Pmode.   
;*****************************
    

and now I have high resolution? As for me I can`t see any change.

One question, how can I keep only white color 32bpp without stripes? And also how to remove the white text cursor from the screen(it`s graphic mode not text, why is he still active)?
Post 16 May 2012, 18:45
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
There something strange here, you should not see white text cursor.
What do you see with above code.
What color is screen ?
Any stripes ?

Any other info of what you see.
Post 16 May 2012, 19:31
View user's profile Send private message Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
I see full screen white color which alternates with vertical lines and white text cursor in left top corner. He appears then disappears with alternating of white color and lines. Question Question Question
Post 16 May 2012, 20:05
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Does this get rid of the stripes ?
Code:
;************************************ 
; By Dex 
; Assemble with fasm  
; c:\fasm Vesa.asm Vesa.bin 
; 
;************************************ 
org 0x7C00  

use16 
;**************************** 
; Realmode startup code. 
;**************************** 

start: 
        xor   ax,ax 
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   sp,0x7C00  

;**************************** 
; Vesa start code. 
;**************************** 

        mov  bx,4115h ; is the mode number 800x600
        mov  ax,4f01h 
        mov  di,Mode_Info        
        mov  cx,bx 
        int  10h  
         
        mov  ax,4f02h 
        int  10h 

;***************************** 
; Setting up, to enter pmode. 
;***************************** 

        cli  
        lgdt  [gdtr] 
         
        mov   eax, cr0 
        or    al,0x1  
        mov   cr0,eax 
  
        jmp   0x10: protected 

;***************************** 
; Pmode.  
;***************************** 

use32 
protected: 
        mov   ax,0x8  
        mov   ds,ax 
        mov   es,ax 
        mov   ss,ax 
        mov   esp,0x7C00 
;***************************** 
; Turn floppy off. 
;***************************** 

        mov   dx,3F2h 
        mov   al,0 
        out   dx,al 

        mov   edi,[ModeInfo_PhysBasePtr]
        mov   ax,0xFFFF
        mov   ecx,800*600  ; if you change mode change these
        rep   stosw
        mov   al,0xFF
        mov   ecx,800*600  ; if you change mode change these
        rep   stosb
Letsloop: 
        hlt 
        jmp   Letsloop 

;************************************* 
; GDT.  
;************************************* 

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000 
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF 
sys_code:   dw    0xFFFF, 0x0000, 0x9800, 0x00CF 
gdt_end: 

gdtr:       dw gdt_end - gdt - 1                                           
            dd gdt  


;************************************* 
; Make program 510 byte's + 0xaa55 
;************************************* 
             
times 510- ($-start)  db 0   
dw 0xaa55 

;************************************* 
; Put uninitialized data here. 
;************************************* 

;=========================================================; 
; Vesa Information Block                         11/12/03 ; 
;---------------------------------------------------------; 
; DOS EXTREME OS V0.01                                    ; 
; by Craig Bamford(Dex).                                  ; 
;                                                         ; 
;=========================================================; 

;============================== VESA MODE INFORMATION =========================================== 
Mode_Info:               
ModeInfo_ModeAttributes         rw      1 
ModeInfo_WinAAttributes         rb      1 
ModeInfo_WinBAttributes         rb      1 
ModeInfo_WinGranularity         rw      1 
ModeInfo_WinSize                rw      1 
ModeInfo_WinASegment            rw      1 
ModeInfo_WinBSegment            rw      1 
ModeInfo_WinFuncPtr             rd      1 
ModeInfo_BytesPerScanLine       rw      1 
ModeInfo_XResolution            rw      1 
ModeInfo_YResolution            rw      1 
ModeInfo_XCharSize              rb      1 
ModeInfo_YCharSize              rb      1 
ModeInfo_NumberOfPlanes         rb      1 
ModeInfo_BitsPerPixel           rb      1 
ModeInfo_NumberOfBanks          rb      1 
ModeInfo_MemoryModel            rb      1 
ModeInfo_BankSize               rb      1 
ModeInfo_NumberOfImagePages     rb      1 
ModeInfo_Reserved_page          rb      1 
ModeInfo_RedMaskSize            rb      1 
ModeInfo_RedMaskPos             rb      1 
ModeInfo_GreenMaskSize          rb      1 
ModeInfo_GreenMaskPos           rb      1 
ModeInfo_BlueMaskSize           rb      1 
ModeInfo_BlueMaskPos            rb      1 
ModeInfo_ReservedMaskSize       rb      1 
ModeInfo_ReservedMaskPos        rb      1 
ModeInfo_DirectColorModeInfo    rb      1 
; VBE 2.0 extensions 
ModeInfo_PhysBasePtr            rd      1 
ModeInfo_OffScreenMemOffset     rd      1 
ModeInfo_OffScreenMemSize       rw      1 

;======================================= START OF PROGRAM  ======================================
    
Post 17 May 2012, 12:42
View user's profile Send private message Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
No result. I recorded a video screen, sorry for bad quality, wrote from the phone.


Description:
Download
Filename: video.zip
Filesize: 35.87 KB
Downloaded: 133 Time(s)

Post 17 May 2012, 16:52
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Thanks for the video, it maybe your mode numbers are not standard.
I will code a test app to get all supported mode from your card, once we have that we can move on.
I will post it later tomorrow.
Post 17 May 2012, 20:38
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac
Here is litle peace of code that i use for to look into the modelist for a mode that provide a resolution we are looking for.
(Additonal it check the EDID of the monitor to make sure that we can set a LFB-vesamode with an own refreshrate.)

Code:
START:    mov      eax, 1              ; Request for feature flags
       DB 0Fh, 0A2h                    ; CPUID instruction
          test     edx, 00800000h      ;  is MMX feature flag(bit 23) set?
          jz  NOMMX

          mov      ax, DATEN           ; Store relative Segmentadress of the Datasegment
        mov      ds, ax              ;  into DS-Segmentregister
     mov      es, ax              ;  into ES-Segmentregister
     mov      di, OFFSET VINF     ; Buffer(512 Bytes) for VESA-Info
      mov      ax, 4F00h           ; Function 0
   int    10h                   ; Get up to 512 Bytes es:di (Datasegment:VINF)
         cmp      ax, 4Fh             ;  succsesfull ?
       jnz NOVESA                   ;   else error: no Vesabios aviable
        cmp     Byte PTR[di+5], 3    ; Compare major version number of Vesa
         jb  NOVESA3                  ;  lesser than Version 3 ?
     lfs      si, [di+0Eh]        ; Get pointer of Modelist in FS:SI
MODE:     mov      cx, fs:[si]         ; Get Modenumber
      lea      si, [si+2]          ; Increase Offset of modelist (instead of add si,2)
    cmp      cx, 0FFFFh          ; End of list ?
        jz  NOMODE
          add      cx, 4000h + 800h    ; VESAnumber + linear + CRTC
   mov      ax, 4F01h           ; Get Mode Info
          mov      di, OFFSET MINF     ; Buffer(256 Bytes) for Mode Info
    int    10h
          cmp      ax, 4Fh
    jnz NOVESA
          cmp     Word PTR[di+12h], MaxX
          jnz MODE
          cmp     Word PTR[di+14h], MaxY
          jnz MODE
      cmp     BYTE PTR[di+19h],20h ; 32 Bits per pixel?
          jnz MODE
          test    BYTE PTR[di], 1      ; Mode supported ?
          jz  NOMODE
          test    BYTE PTR[di], 80h    ; Linear access supported ?
          jz NOLIN
    cmp     DWORD PTR[di+28h], 0 ; Linear Offset to the framebuffer aviable ?
          jz  NOLIN
    test    BYTE PTR[di+1], 4    ; Triple buffering supported ?
          jz  NOTRIP
          mov      eax, DWORD PTR[di+3Eh]  ; Get MaxPixelClock
          cmp      eax, DWORD PTR[PIXCLOC] ;  and compare with our CRTC-Value
          jb  NOCLOC                       ;  if lesser than Error: No pixelcloc
          mov      bp, cx              ; Store the modenumber
;--------------------------------------
          mov      ax, 4F0Bh           ; Get/set Pixel-Clock
          mov      dx, cx
          xor      bl, bl              ; Get
          mov      ecx, DWORD PTR[PIXCLOC]
          int    10h
          cmp      ax, 4Fh
          jnz NOCLOC                   ; Error: No pixelcloc
          mov      DWORD PTR[PIXCLOC], ecx
;--------------------------
          xor      eax, eax            ; Calculate Refreshrate
          mov      ax, [CRTC]          ; Horizontal Total
          xor      ebx, ebx
          mov      bx, [VERTOTA]       ; Vertikal Total
          mul      ebx
          mov      ebx, eax
          mov      eax, ecx            ; Pixelcloc
          mov      esi, 10
          xor      edx, edx
          div      esi
          xor      edx, edx
          div      ebx
          mov      [REFRATE], ax       ; RefreshRate=Pixelcloc/(HTotal*Vtotal)
;--------------------------------------
   mov      ax, 4F15h           ; DDC - INSTALLATION CHECK
     xor      bl, bl              ; = 0 for to get the monitor information
       int    10h
          cmp      ax, 4Fh
    jnz NODDC
   mov      ax, 4F15h           ; DDC - READ EDID
      mov      bl, 1
      xor      cx, cx
     xor      dx, dx
     mov      di, OFFSET EDID
    int    10h
          mov      eax, 0FD000000h     ; Text-identifier V/H range
    mov      bx, 36h
    cmp      [di+bx], eax        ; di+36h detailed timing #1
    jz  short H1
        lea      bx, [bx+12h]        ;  (add bx,12h)
        cmp      [di+bx], eax        ; di+48h detailed timing #2
    jz  short H1
        lea      bx, [bx+12h]
       cmp      [di+bx], eax        ; di+5Ah detailed timing #3
    jz  short H1
        lea      bx, [bx+12h]
       cmp      [di+bx], eax        ; di+6Ch detailed timing #4
    jnz NODDC
H1:       cmp     BYTE PTR[di+bx+6], MAXHZ
          jb  NOHZ
   cmp     BYTE PTR[di+bx+8], MAXKHZ
          jb  NOKHZ
;--------------------------------------
          mov      ax, 4F02h           ; Switch to the requested vesamode
          mov      bx, bp              ;  with an access to the linear framebuffer
          mov      di, OFFSET CRTC     ;  and with an own Video-Timing(..refreshrate)
          int    10h
          cmp      ax, 4Fh
          jnz NOMODE                   ; ERROR: No Vesamode
    

I wrote this pure 16 Bit DOS-application that demonstrate how to use a vesamode with a resolution of 1024 x 768 x 32 with an own refreshrate of 100hz and additionaly it demonstrate how to use the linear framebuffer with hardware triple buffering. To enable an access to the linear framebuffer i prefer the unrealmode/bigrealmode. For to use the unrealmode/bigrealmode we have to remove/REM any memmory manager like emm386.exe in our config.sys before.
After rebooting without it we can start the aplication.

Goal of the aplication:
If the application starts without any error message, then the application switch into the vesamode and begin to move some balls across the screen and if they reached a border of the screen, then they turn their direction.
For to terminate the application and to switch back to DOS in the textmode(3) please press any key on your keyboard.

Minimum system requirements:
Operating system: DOS 5, 6, or DOS 7 (a part of Windows98/ME)
(not working under windows(DOSbox) and not working with a memmory manager like emm386.exe)
MMX-CPU (tested on AMD Palomino 1800+@1550mhz and on AMD Tbred 2700+@2100mhz; Socket A mainboard with AGP)
Fully working vesa 3 Bios (tested on MSI NVIDIA Geforce 4 TI 4200 64MB AGPx4 // failed with Powercolor ATI x800 pro(VBE3 256MB AGPx8))
CRT-Monitor with DDC and 96 khz (tested on 19" Samsung 940 and on 19" SAMTRON 96P)

Download: http://www.alice-dsl.net/freecracmaps/Tool/Neutrip.zip

Used resources:
Public documents from vesa.org(register and/or login):
EEDIDguideV1.pdf
vbe3.pdf

Dirk
Post 18 May 2012, 04:40
View user's profile Send private message Send e-mail Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 240
Location: the-ideom
Mike Gonta
freecrac wrote:
Used resources:
Public documents from vesa.org(register and/or login):
EEDIDguideV1.pdf
vbe3.pdf
Archived here:
http://web.archive.org/web/20061231170010/http://www.vesa.org/Public/

_________________
Mike Gonta
the-ideom - now you know how to compile

https://mikegonta.com
Post 18 May 2012, 07:15
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
freecrac wrote:

Code:
       DB 0Fh, 0A2h                    ; CPUID instruction

          jnz NOMODE                   ; ERROR: No Vesamode
    


fasm supports the cpuid instruction, no need to do it the raw way.

and you should also avoid UPCASE for labels. UPCASE is generaly for EQUATES.
Post 18 May 2012, 11:17
View user's profile Send private message Visit poster's website Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
One more question about VESA. For example I have native 1600x900 resolution on my monitor and I use 1024x768 VESA resolution. As I know 1024x768 it means that I have on my screen:

_________ column 0; _ column 1; _ column 2; ................ column 1023
row 0 ._.| pixel 0 __. | pixel 1 __. | pixel 2 __ | ............... | pixel 1023 |
row 1 ._.| pixel 1024 | pixel 1025 | pixel 1026 | ............... | pixel 2047 |
row 2 ._.| pixel 2048 | pixel 2049 | pixel 2050 | ............... | pixel 3071 |
...........
row 767 |pix 785408 |pix 785409 |pix 785410 | ............... |pix 786431 |

As I understand, for address all pixels(1600x900) than in column[0,0] ... column[1023, 767] submitted information not of one pixel but about several pixels. That`s why low resolution is produced. But if my video card support 1600x1200 (122h) I will be used all columns from 0 to 1599 but only 900(0...899) rows from 1200, so it must by like native resolution of my monitor??? Question Question Question


Last edited by Rusik on 07 Jan 2013, 09:44; edited 1 time in total
Post 18 May 2012, 12:05
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac
edfed wrote:
freecrac wrote:

Code:
       DB 0Fh, 0A2h                    ; CPUID instruction

          jnz NOMODE                   ; ERROR: No Vesamode
    


fasm supports the cpuid instruction, no need to do it the raw way.

Ok. I hope the diffence in this code for "MASM 5" is not so far away, so that anybody can simple edit and assimilate the code for fasm.
(MASM 6 also support the the cpuid instruction and adiitional also mmx, sse,3dnow, but for MASM 5 we have to handcode those instructions.)

Quote:
and you should also avoid UPCASE for labels. UPCASE is generaly for EQUATES.

I do not know about an agreement of a special format for a generaly style of a code. And i am sorry, i do not like UPCASE for EQUATES and i always use UPCASE for labels.

...

@Mike Gonta: Hello Mike, i remember you, because some years ago we met us first in comp.lang.asm.x86 and/or alt.lang.asm
Between then and now i found evermore postings from you, so i know you have done a great job on your way.

I think vesa.org change their own internet presence, because they want that we have to register us and to login before we can download those manuals. Some years ago it was possible to spread out a direct link to the manuals on vesa.org. But today this page where we can find those manuels on vesa.org become with every new access of this page also a new link address only for one access. If we left this page, then the link will be invalid.

I am not sure if the "web.archive.org" authorized to spread out this manuals from vesa.org.

Dirk
Post 18 May 2012, 23:27
View user's profile Send private message Send e-mail Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac
Rusik wrote:
One more question about VESA. For example I have native 1600x900 resolution on my monitor and I use 1024x768 VESA resolution. As I know 1024x768 it means that I have on my screen:

_________ column 0; _ column 1; _ column 2; ................ column 1023
row 0 ._.| pixel 0 __. | pixel 2 __. | pixel 3 __ | ............... | pixel 1023 |
row 1 ._.| pixel 1024 | pixel 1025 | pixel 1026 | ............... | pixel 2047 |
row 2 ._.| pixel 2048 | pixel 2049 | pixel 2050 | ............... | pixel 3071 |
...........
row 767 |pix 785408 |pix 785409 |pix 785410 | ............... |pix 786431 |

As I understand, for address all pixels(1600x900) than in column[0,0] ... column[1023, 767] submitted information not of one pixel but about several pixels. That`s why low resolution is produced. But if my video card support 1600x1200 (122h) I will be used all columns from 0 to 1599 but only 900(0...899) rows from 1200, so it must by like native resolution of my monitor??? Question Question Question

The interpolation stretch or clinch the pixel to fit the screen:
http://www.prad.de/en/monitore/shownews_lex82.html
http://www.prad.de/en/monitore/shownews_lex81.html

Dirk
Post 18 May 2012, 23:48
View user's profile Send private message Send e-mail Reply with quote
Rusik



Joined: 09 Apr 2012
Posts: 21
Location: Ukraine, Kyiv
Rusik
Thanks for the link freecrac Very Happy ,where you were before with this links Smile

If I understood correctly:
If VESA mode with low resolution(320x200, 640x480 etc) then used stretching interpolation. But if VESA mode have higher resolution than the monitor, for example 1600x1200 VESA to 1600x900 monitor, what is done in this case, pressing interpolation???
Post 19 May 2012, 09:42
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
when the screen is smaller than the graphics card resolution, the screen becomes a window, and you can scroll on the full resolution using this window.
Post 19 May 2012, 14:29
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.