Linear Frame Buffer
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Linear Frame Buffer
Is it necessary to be in protected mode for implementing Linear Frame Buffer? If no, then is there a good documentation or tutorial explaining in details the way of implementing linear frame buffer in real mode?
Regards
Nitin
Nitin
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
It all depends on what you expect. Most recent cards have a lot of video memory and you cant possibly fit that in the lower 1MB. However, Most cards still support VGA modes, so if you think 64k is enough, you can simply go to mode 0x13 and enjoy a linear framebuffer at A000:0000-A000:ffff.
If you're desparate about staying in real mode, go unREAL, and you can access any linear frambuffer whatever the size and specs.
In unreal mode, i think the pm tutorials give you an idea how to work it. In real mode, either type MOV AX, 0x13 INT 0x10 or learn to program VGA registers.
I'm not really of the tutorial type, so i cant find those for you
If you're desparate about staying in real mode, go unREAL, and you can access any linear frambuffer whatever the size and specs.
In unreal mode, i think the pm tutorials give you an idea how to work it. In real mode, either type MOV AX, 0x13 INT 0x10 or learn to program VGA registers.
I'm not really of the tutorial type, so i cant find those for you
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
So this means I cannot stay in pure real mode and use linear frame buffer for 1024x768 16bit video mode as it will occupy more space. However, 800x600 16 bit which will occupy less than 1mb can be used right?It all depends on what you expect. Most recent cards have a lot of video memory and you cant possibly fit that in the lower 1MB.
Regards
Nitin
Nitin
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
800x600x16 fits in 256k, but not in the VGA's 64k window. If you really want a linear framebuffer to fill the space between 0xA0000 and 0xDFFFF, you are dependent on the chipset and video card to monitor accesses in that area correctly. That said, you can only really rely on 64k of linear framebuffer to be always present, effectively rendering high resolutions impossible without using banking or VGA write modes.
If you wish to stick to pure realmode and keep things working, i suggest you learn how to control the display the MSDOS way
If you wish to stick to pure realmode and keep things working, i suggest you learn how to control the display the MSDOS way
You couldn't define physical address of LBF; for instance, LBF is my nvidia box is 0xE0000000. I have to underline that is Physical Address... Far beyond the ram limits... I have only 256mb ram
however; maybe (just maybe ?) you would use int 15h ah=87h to write this locations from Rmode...
http://www.htl-steyr.ac.at/~morg/pcinfo ... te7do0.htm
P.S: I didn't test it...
however; maybe (just maybe ?) you would use int 15h ah=87h to write this locations from Rmode...
http://www.htl-steyr.ac.at/~morg/pcinfo ... te7do0.htm
P.S: I didn't test it...
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Ok then I guess unreal mode will do right?
But I tried that and all that I see is blank screen
Any suggestions
But I tried that and all that I see is blank screen
Code: Select all
[ORG 0x7c00] ; add to offsets
start: xor ax, ax ; make it zero
mov ds, ax ; DS=0
mov ss, ax ; stack starts at 0
mov sp, 0x9c00 ; 200h past code start
mov ax,00
mov es,ax
mov ah,0x4F
mov al,00h
mov di, temp
int 0x10
;; getting physical ptr
mov ah,0x4F
mov al,01h
mov ch,01000001b
mov cl,11h
mov di, temp
int 0x10
mov dword edx, [temp + 28h]
;changing video mode
mov ah,0x4F
mov al,02h
mov bh,01000001b ; 640x480x16 with linear frame buffer
mov bl,11h
int 0x10
cli ; no interrupt
push ds ; save real mode
push es
lgdt [gdtinfo] ; load gdt register
mov eax, cr0 ; switch to pmode by
or al,1 ; set pmode bit
mov cr0, eax
mov bx, 0x08 ; select descriptor 1
mov es,bx
mov ds, bx ; 8h = 1000b
and al,0xFE ; back to realmode
mov cr0, eax ; by toggling bit again
pop es
pop ds ; get back old segment
sti
mov bx, 0xFFFF ; some color
mov word [ds:edx], bx
jmp $ ; loop forevers
gdtinfo:
dw gdt_end - gdt - 1 ;last byte in table
dd gdt ;start of table
gdt dd 0,0 ; entry 0 is always unused
flatdesc db 0xff, 0xff, 0, 0, 0, 10010010b, 01001111b, 0
gdt_end:
temp:
VESASignature db 'VESA' ; 4 signature bytes
VESAVersion dw 0 ; VESA version number
OEMStringPtr dd 0 ; Pointer to OEM string
Capabilities times 4 db 0 ; capabilities of the video environment
VideoModePtr dd 0 ; pointer to supported Super VGA modes
TotalMemory dw 0 ; Number of 64kb memory blocks on board
times 510-($-$$) db 0 ; fill sector w/ 0's
db 0x55 ; req'd by some BIOSes
db 0xAA
Regards
Nitin
Nitin
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Hi,
For video mode numbers used by the VBE "set video mode" function, BX contains the video mode number itself, and a set of flags which control how that video mode should be setup.
It's probably a good idea to read the specification to see what these flags are. It'll also help to see if there's anything else you may have missed, like how to determine if the video mode is supported and which mode number to use, how to determine if a video mode supports the linear frame buffer, the note on page 15 that says manufacturers don't need to use the old "pre-defined" mode numbers (e.g. video mode 0x101 could be any video mode, not just 640*480), etc.
Cheers,
Brendan
Perhaps you've overlooked something in the VBE specification?nitinjavakid wrote:People please help me. I am totally confused.
For video mode numbers used by the VBE "set video mode" function, BX contains the video mode number itself, and a set of flags which control how that video mode should be setup.
It's probably a good idea to read the specification to see what these flags are. It'll also help to see if there's anything else you may have missed, like how to determine if the video mode is supported and which mode number to use, how to determine if a video mode supports the linear frame buffer, the note on page 15 that says manufacturers don't need to use the old "pre-defined" mode numbers (e.g. video mode 0x101 could be any video mode, not just 640*480), etc.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
For video mode numbers used by the VBE "set video mode" function, BX contains the video mode number itself, and a set of flags which control how that video mode should be setup.
Code: Select all
;changing video mode
mov ah,0x4F
mov al,02h
mov bh,01000001b ; 640x480x16 with linear frame buffer
mov bl,11h
int 0x10
Also the screenshot shows that the video memory is not full cleared
D15 of bx if not set clears the display memory I guess.
- Attachments
-
- Screenshot (take a closer look)
- untitled.JPG (5.4 KiB) Viewed 3405 times
Regards
Nitin
Nitin
Hi,
That picture is interesting...
Was the screen cleared, and did your write cause those grey dots?
For 16 colour modes the display memory is usually split into 4 "planes" where each plane contains the 1 bit of the colour for each pixel. There's also registers in the VGA card that mask different pixels, mask different planes, and to set different write modes.
The colour "dark grey" comes from all bits clear in the first 3 planes (blue, green and red components), with bits set in the last plane (the intensity) - dark grey is actually "bright black". Normally the VGA registers are configured to only allow writes to one plane at a time - it's possible that this register was left in a state that allow writes to the fourth (intensity) plane, which is causing the dark grey colour.
This doesn't explain the location of the pixels though - I can't figure out why they wouldn't be at the top left.
The other interesting thing is that you've got a screen-shot. This tells me you're using an emulator. Because 640*480*16 colour mode is a standard VGA mode, most people would just use the 64 KB area at 0x000A0000, so it's possible that which-ever emulator you're using has bugs with this mode that no-one else has tried using.
Out of curiousity I took a look at the source code for the LGPL VGA BIOS (used by both Bochs and Qemu). For the "set VBE mode" function, it does "pusha", then calls some C code, then does "popa" before returning. Now I'm wondering if the C code modifies EDX, and the "popa" only restores the lower 16 bits, leaving the upper 16 bits of EDX in an unknown state.
Anyway, would you mind doing some tests?
First, comment out the "mov [ds:edx],bx" instruction and see if those grey dots disappear. If they do, then the screen is being cleared. If they're still there then you've probably got a buggy emulator.
Next, shift the "mov dword edx, [temp + 28h]" instruction to just above the "mov [ds:edx],bx" and see if the grey dots move to the top left (and possibly, change colour). If nothing changes then EDX isn't being trashed by the VBE BIOS.
Let me know how it goes, and depending on results there might be some VGA registers to play....
Cheers,
Brendan
That picture is interesting...
Was the screen cleared, and did your write cause those grey dots?
For 16 colour modes the display memory is usually split into 4 "planes" where each plane contains the 1 bit of the colour for each pixel. There's also registers in the VGA card that mask different pixels, mask different planes, and to set different write modes.
The colour "dark grey" comes from all bits clear in the first 3 planes (blue, green and red components), with bits set in the last plane (the intensity) - dark grey is actually "bright black". Normally the VGA registers are configured to only allow writes to one plane at a time - it's possible that this register was left in a state that allow writes to the fourth (intensity) plane, which is causing the dark grey colour.
This doesn't explain the location of the pixels though - I can't figure out why they wouldn't be at the top left.
The other interesting thing is that you've got a screen-shot. This tells me you're using an emulator. Because 640*480*16 colour mode is a standard VGA mode, most people would just use the 64 KB area at 0x000A0000, so it's possible that which-ever emulator you're using has bugs with this mode that no-one else has tried using.
Out of curiousity I took a look at the source code for the LGPL VGA BIOS (used by both Bochs and Qemu). For the "set VBE mode" function, it does "pusha", then calls some C code, then does "popa" before returning. Now I'm wondering if the C code modifies EDX, and the "popa" only restores the lower 16 bits, leaving the upper 16 bits of EDX in an unknown state.
Anyway, would you mind doing some tests?
First, comment out the "mov [ds:edx],bx" instruction and see if those grey dots disappear. If they do, then the screen is being cleared. If they're still there then you've probably got a buggy emulator.
Next, shift the "mov dword edx, [temp + 28h]" instruction to just above the "mov [ds:edx],bx" and see if the grey dots move to the top left (and possibly, change colour). If nothing changes then EDX isn't being trashed by the VBE BIOS.
Let me know how it goes, and depending on results there might be some VGA registers to play....
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- nitinjavakid
- Member
- Posts: 65
- Joined: Sat Oct 21, 2006 11:28 am
- Location: Exams over!
- Contact:
Well I am using VMware and those grey dots werent drawn by me .
Also, the current video mode is 16bit[2^16 colors] (sorry didnt clarify that).
Yup those grey dots dont disappear after commenting. So, I concluded that the screen is not getting cleared even after specifying that in set mode bx field. That was one of my doubts.
Also, there was no effect on these grey dots no matter where I keep the mov dword edx,[ds:temp] instruction.
All in all I am a bit confused with the unexpected results
Also, the current video mode is 16bit[2^16 colors] (sorry didnt clarify that).
Yup those grey dots dont disappear after commenting. So, I concluded that the screen is not getting cleared even after specifying that in set mode bx field. That was one of my doubts.
Also, there was no effect on these grey dots no matter where I keep the mov dword edx,[ds:temp] instruction.
All in all I am a bit confused with the unexpected results
Regards
Nitin
Nitin
@nitinjavakid:
your code shouldn't switch to unreal mode because TLBs are empty.
To switch unreal mode:
1)Switch to Pmode
Setting 0. bit of cr0 did not forward you to pmode, after that you should change CS too
2)Switch back to real mode
Now your TLBs were filled and you will be unreal mode...
(P.S.: And ofcourse only clearing 0.bit of cr0 doesn't make any changes, you must change CS too)
your code shouldn't switch to unreal mode because TLBs are empty.
To switch unreal mode:
1)Switch to Pmode
Setting 0. bit of cr0 did not forward you to pmode, after that you should change CS too
2)Switch back to real mode
Now your TLBs were filled and you will be unreal mode...
(P.S.: And ofcourse only clearing 0.bit of cr0 doesn't make any changes, you must change CS too)
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Eh, unreal mode has nothing to do with TLBs:
The TLBs are the Translation Lookaside Buffer. They cache page table contents, so that the processor can quickly look up an physical address given an linear address.
Unreal mode goes about the descriptor cache. When you load a segment register, the CPU will load the base, limit, and privilege options for quick access. In real mode, it'll set the base according to the value, but not the limit. In protected mode, the entire descriptor cache for that segment register is reloaded.
So to get unreal mode, we enter protected mode, and we load the ds and es registers, causing their entire descriptor caches to be flushed and reloaded. After that we leave protected mode, load ds and es again, so the base gets set, but NOT the limit.
Setting PE in CR0 will immediately cause an entry to protected mode, however the segment registers and the corresponding caches are still set to real mode values. So although it appears as if you are still in real mode, the code is executed as if it were 16-bit ring 0 protected mode code. Which is nevertheless pretty close to real mode in behaviour.
So unless i'm really mistaken, the unreal mode part has got the correct design.
To test it, dont set a video mode, and after setting DS and ES try large address writes to video memory, like
mov EBX, 0xB8000
mov [EBX], AX
to print characters to the screen.
The only problem i can forsee with unreal mode is that vmware doesn't support it. But since i dont use unreal mode nor vmware I have no clue wether it does or not.
The TLBs are the Translation Lookaside Buffer. They cache page table contents, so that the processor can quickly look up an physical address given an linear address.
Unreal mode goes about the descriptor cache. When you load a segment register, the CPU will load the base, limit, and privilege options for quick access. In real mode, it'll set the base according to the value, but not the limit. In protected mode, the entire descriptor cache for that segment register is reloaded.
So to get unreal mode, we enter protected mode, and we load the ds and es registers, causing their entire descriptor caches to be flushed and reloaded. After that we leave protected mode, load ds and es again, so the base gets set, but NOT the limit.
Setting PE in CR0 will immediately cause an entry to protected mode, however the segment registers and the corresponding caches are still set to real mode values. So although it appears as if you are still in real mode, the code is executed as if it were 16-bit ring 0 protected mode code. Which is nevertheless pretty close to real mode in behaviour.
So unless i'm really mistaken, the unreal mode part has got the correct design.
To test it, dont set a video mode, and after setting DS and ES try large address writes to video memory, like
mov EBX, 0xB8000
mov [EBX], AX
to print characters to the screen.
The only problem i can forsee with unreal mode is that vmware doesn't support it. But since i dont use unreal mode nor vmware I have no clue wether it does or not.