flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Simple example of Vesa driver?[solved] |
Author |
|
Dex4u 04 Feb 2012, 23:36
First in real terms, you need to set vesa mode in realmode, than you can use it in PMode
Heres a simple example: 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 ====================================== This set vesa mode in realmode (640x480 32bpp) and switchs to pmdode. And fades the screen color. To write just one pixel you would do this Code: mov edi,dword[ModeInfo_PhysBasePtr] ; points to screen mov eax,0x00ffffff ; color stosd ; write color whats in eax, to the address thats in edi (screen ) Some things to note: If you test in emulator alot now do not support 640x480 32bpp, so you may need to use Code: ;**************************** ; Vesa start code. ;**************************** mov bx,4115h instead of Code: ;**************************** ; Vesa start code. ;**************************** mov bx,4112h Which is 800x600 32bpp and the about code would need moding to fill the screen right. Also this code does not enable A20 which means you will only be able to fill 3/4 of screen. Last edited by Dex4u on 05 Feb 2012, 19:55; edited 1 time in total |
|||
04 Feb 2012, 23:36 |
|
binary 05 Feb 2012, 10:55
Thank you ,it works.
One thing I don't understand , ModeInfo_PhysBasePtr is the location of the pixel on screen? i tried modifying the value in ModeInfo_PhysBasePtr and the pixel is in the same position.How do I change the position? |
|||
05 Feb 2012, 10:55 |
|
cod3b453 05 Feb 2012, 11:37
ModeInfo_PhysBasePtr is the pointer to the linear frame buffer (LFB) where the screen memory starts. Each pixel is some offset from this value, as follows:
Quote: offset = ((y * ModeInfo_XResolution) + x) * (bpp / 8 ) So to write a 32bpp pixel at (x,y) you'd write to address: Quote: ModeInfo_PhysBasePtr + (((y * ModeInfo_XResolution) + x) * 4) Code: mov edi,dword [ModeInfo_PhysBasePtr] mov eax,dword [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword [y] ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword [x] ; eax = (y * ScreenWidth) + x mov dword [edi+4*eax],0x00FFFFFF ; ModeInfo_PhysBasePtr + ((y * ScreenWidth) + x) * 4 |
|||
05 Feb 2012, 11:37 |
|
binary 05 Feb 2012, 12:42
Thanks for the formula and clarification , I tried that code and for some reason the pixel doesn't show up on screen.I'm using 1024 /768 resolution
I also tried like this: Code: mov edi,dword [ModeInfo_PhysBasePtr] mov eax,dword [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 20 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 20 mov ebx,dword 4 xor edx,edx mul ebx add eax,edi mov dword [eax],0x00FFFFFF Code: ;************************************ ; By Dex ; Assemble with fasm ; c:\fasm vesa.asm vesa.bin ; ;************************************ use16 org 7C00h ;**************************** ; Realmode startup code. ;**************************** ; a20 in al, 0x92 or al, 2 out 0x92, al start: push cs pop ds push ds pop es ;**************************** ; Vesa start code. ;**************************** mov bx,4118h 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. Wink ;***************************** use32 protected: mov ax,0x8 mov ds,ax mov es,ax mov ss,ax ;***************************** ; Turn floppy off. ;***************************** mov dx,3F2h mov al,0 out dx,al ; print pixel mov edi,dword [ModeInfo_PhysBasePtr] mov eax,dword [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 20 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 20 mov dword [edi+4*eax],0x00FFFFFF ;mov edi,dword[edi+4*eax] ; points to screen ;mov eax,0x00aabbcc ; color ;stosd ; write color whats in eax, to the address thats in edi (screen ) hlt ;************************************* ; 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 ;============================== 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 1024 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 20 ModeInfo_OffScreenMemOffset rd 1 ModeInfo_OffScreenMemSize rw 1 times 510-($-$$) db 0 dw 0xAA55 |
|||
05 Feb 2012, 12:42 |
|
cod3b453 05 Feb 2012, 13:15
First thing I noticed is you have corrupted the ModeInfo definition rw reserves words, so you need to put those values back to 1. This table is overwritten by the int 0x10 ax = 0x4F01 mode info BIOS call, so you can't store any data here; the actual resolution is determined by the value you give in bx for the int 0x10 ax = 0x4F02 call. (This is defined in VBE2 see http://www.ctyme.com/intr/rb-0275.htm)
|
|||
05 Feb 2012, 13:15 |
|
binary 05 Feb 2012, 15:34
After that correction is still not working.I don't understand what is causing the problem.
|
|||
05 Feb 2012, 15:34 |
|
cod3b453 05 Feb 2012, 16:06
I'm not sure how it managed to compile before but I moved the table memory after the boot sector and corrected the size of the ModeInfo_XResolution (my mistake):
Code: ;************************************ ; By Dex ; Assemble with fasm ; c:\fasm vesa.asm vesa.bin ; ;************************************ use16 org 7C00h ;**************************** ; Realmode startup code. ;**************************** ; a20 in al, 0x92 or al, 2 out 0x92, al start: push cs pop ds push ds pop es ;**************************** ; Vesa start code. ;**************************** mov bx,4118h 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. Wink ;***************************** use32 protected: mov ax,0x8 mov ds,ax mov es,ax mov ss,ax ;***************************** ; Turn floppy off. ;***************************** mov dx,3F2h mov al,0 out dx,al ; print pixel mov edi,dword [ModeInfo_PhysBasePtr] movzx eax,word [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 20 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 20 mov dword [edi+4*eax],0x00FFFFFF ;mov edi,dword[edi+4*eax] ; points to screen ;mov eax,0x00aabbcc ; color ;stosd ; write color whats in eax, to the address thats in edi (screen ) hlt ;************************************* ; 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 times 510-($-$$) db 0 dw 0xAA55 ;============================== 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 |
|||
05 Feb 2012, 16:06 |
|
binary 05 Feb 2012, 17:08
This works but it prints one pixel yellow and anoter one beside it blue instead of one pixel white
Code: mov edi,dword [ModeInfo_PhysBasePtr] movzx eax,word [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 20 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 20 mov dword [edi+4*eax],0x00FFFFFF This works as it should but with 3 insted of 4 like this Code: mov edi,dword [ModeInfo_PhysBasePtr] mov dword [edi+3*1025],0x00FFFFFF If I do it like this it doesn't work. Code: mov edi,dword [ModeInfo_PhysBasePtr] mov eax,dword [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 1 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 0 mov ebx,dword 4 xor edx,edx mul ebx add eax,edi mov dword [eax],0x00FFFFFF If I do it like this it doesn't compile( putting 3 instead of 4 ) Code: mov edi,dword [ModeInfo_PhysBasePtr] movzx eax,word [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 10 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 10 mov dword [edi+3*eax],0x00FFFFFF I'm using Qemu too |
|||
05 Feb 2012, 17:08 |
|
cod3b453 05 Feb 2012, 17:22
Yes QEMU only supports 24bpp - to support both you'll need another multiply by ModeInfo_BitsPerPixel shifted right by 3 (faster divide by and use [edi+eax].
|
|||
05 Feb 2012, 17:22 |
|
binary 05 Feb 2012, 17:34
You meant something like this?
Code: mov edi,dword [ModeInfo_PhysBasePtr] mov eax,dword [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 1 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 0 mov ecx , eax movzx eax,word [ModeInfo_BitsPerPixel] mov ebx, ecx xor edx,edx mul ebx shr eax , 3 mov dword [eax],0x00FFFFFF I tried that and no luck |
|||
05 Feb 2012, 17:34 |
|
cod3b453 05 Feb 2012, 17:50
You've missed the base address in edi and ModeInfo_BitsPerPixel is a byte:
Code: mov edi,dword [ModeInfo_PhysBasePtr] movzx eax,word [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 1 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 0 movzx ebx,byte [ModeInfo_BitsPerPixel] shr ebx,3 mul ebx mov dword [edi+eax],0x00FFFFFF |
|||
05 Feb 2012, 17:50 |
|
binary 05 Feb 2012, 17:54
thank you
|
|||
05 Feb 2012, 17:54 |
|
Dex4u 05 Feb 2012, 20:12
I posted the wrong code, i have added the new code above.
Note: vesa of that mode have two different implementations. Some use 24 bits per pixel others use 32 bits per pixel. You need to do this Code: ;***************************** ; Do we have 32 BitsPerPixel. ;***************************** cmp byte[ModeInfo_BitsPerPixel],32 je Its32BPP cmp byte[ModeInfo_BitsPerPixel],24 jne exitHere Its24BPP: ; Put your 24bpp cod here jmp exitHere Its32BPP: ; Put your 32bpp cod here exitHere: Normal you use a screen buffer thats is set to 32bpp say and write all you code as 32bpp, you then only need to check and write the differant buffer to screen code when you write buffer to screen. Also do not forget about A20, as most emulator do it anyway, its not until you test on real PC you find a problem. |
|||
05 Feb 2012, 20:12 |
|
binary 06 Feb 2012, 20:16
For 32 bits I should simply put this?
Code: mov edi,dword [ModeInfo_PhysBasePtr] movzx eax,word [ModeInfo_XResolution] ; eax = ScreenWidth mov ebx,dword 4 ; ebx = y xor edx,edx ; edx = 0 mul ebx ; (edx:)eax = y * ScreenWidth add eax,dword 6 mov dword [edi+eax],0x00FFFFFF I tried the 24 bit vertion on Qemu and bochs and works on both of them |
|||
06 Feb 2012, 20:16 |
|
cod3b453 09 Feb 2012, 19:33
You still need to mulitply:
Code: mov dword [edi+4*eax] If you only want to support 32bit this is fine, otherwise it's easier to use the previous version to support both bodes without having to maintain two versions of the code. This is what I ended up doing so I could test on Virtualbox and QEMU |
|||
09 Feb 2012, 19:33 |
|
flash 06 Apr 2012, 05:51
Tempting luck, it is possible to make the access code very similar to the one to access vga framebuffer in real mode.
Almost in qemu, all standar vesa modes points linear framebuffer address at 0xf0000000. For this reason, once you have video mode set and in protected mode, works fine: Code: mov ebx,0xf0000000 ; points the LFB mov edi,(x + y*mode_width)*Bpp ; note Bpp means bytes per pixel mov eax,color_code mov [ebx+edi],eax So, essentially your task is to set video mode and take care about screen geometry |
|||
06 Apr 2012, 05:51 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.