640x480x16 double buffer
- codemastersnake
- Member
- Posts: 148
- Joined: Sun Nov 07, 2004 12:00 am
- Contact:
Re: 640x480x16 double buffer
I would really suggest the double buffering technique that was used back in good ol' dayz when DOS games existed....
It's pretty quick and was used professionally...
I think following algo could work as well:
1) create a buffer in main memory
2) create a pointer to video memory
3) update all the things in buffer not directly to video memory
4) install a timer that updates screen by using data from buffer after a specific interval
5) the timer IRQ should manage retrace and all the hardware related problems...
I guess I just discovered a way well maybe I'll use it in my OS's next release...
What do you all have to say about this psuedo code?
It's pretty quick and was used professionally...
I think following algo could work as well:
1) create a buffer in main memory
2) create a pointer to video memory
3) update all the things in buffer not directly to video memory
4) install a timer that updates screen by using data from buffer after a specific interval
5) the timer IRQ should manage retrace and all the hardware related problems...
I guess I just discovered a way well maybe I'll use it in my OS's next release...
What do you all have to say about this psuedo code?
- 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:
Re: 640x480x16 double buffer
Let's just call that software triple-buffering from the start
-
- Member
- Posts: 2566
- Joined: Sun Jan 14, 2007 9:15 pm
- Libera.chat IRC: miselin
- Location: Sydney, Australia (I come from a land down under!)
- Contact:
Re: 640x480x16 double buffer
For even faster implementation you could use dirty rectangles, which are basically regions of that in-RAM buffer that need to be copied to video RAM. So, rather than copying the entire buffer, you only copy regions that have been updated since the last redraw.
Although, you might want to actually get a GUI working first before you worry about things like that, otherwise you'll not know whether the reason your screen is going blank is the dirty rectangles implementation or something wrong in your GUI code.
Although, you might want to actually get a GUI working first before you worry about things like that, otherwise you'll not know whether the reason your screen is going blank is the dirty rectangles implementation or something wrong in your GUI code.
Re: 640x480x16 double buffer
Hi guy's
I studied your comment well and
developed this programe,...,i need your reply
note: use Turob C++ 3.1 compiler with large memory model
I studied your comment well and
developed this programe,...,i need your reply
note: use Turob C++ 3.1 compiler with large memory model
Code: Select all
#define buffer_base 0x50000000L //my buffer segment
#define size 38400 //bytes
enum type0x12{save=1,load};
typedef unsigned char far fbyte;
void screen0x12(type0x12 rw){
for(int i=0; i<3; i++){//Cycle through 4 bit plane of EGA/VGA.
if(rw==load){//load buffer
outp(0x3c4,2);//index the map register.
outp(0x3c5,(int)pow(2.0,(float)i));//Bit plane to reference.
//Load each segment into its corresponding bit plane.
_fmemcpy((fbyte)0xA0000000L,(void far*)(buffer_base+(i*0x10000000L)),size);
}
else{//save to buffer
outp(0x3ce,4);//Select Read Map Select Register.
outp(0x3cf,i);//Select the bit plane to save.
_fmemcpy((void far*)(buffer_base+(i*0x10000000L)),(fbyte)0xA0000000L,size);
}
}
}
Distance doesn't make you any smaller,
but it does make you part of a larger picture.
but it does make you part of a larger picture.
Re: 640x480x16 double buffer
I have no idea what this program does, however I would like to highlight some points concerning the code.
First,
If you have four bit planes, it should be
My other point is
Using a bit shift is much faster, especially under Turbo C or Turbo Pascal, which uses emulation for floating-point instructions.
Besides,
If you are in real mode, you need to use segmented addressing. If I remember correctly, you have to use a MK_FP macro, or something similar.
Pushing a long value (32-bit in real mode) down the stack may work, because it is interpreted as segment:offset by the function called, however it may break anytime you change the address.
First,
Code: Select all
void screen0x12(type0x12 rw)
{
for(int i=0; i<3; i++){//Cycle through 4 bit plane of EGA/VGA.
Code: Select all
for(int i=0; i<4; i++){//Cycle through 4 bit plane of EGA/VGA.
Code: Select all
outp(0x3c4,2);//index the map register.
outp(0x3c5,(int)pow(2.0,(float)i));//Bit plane to reference.
Code: Select all
outp(0x3c4,2);//index the map register.
outp(0x3c5, 1 << i);//Bit plane to reference.
Code: Select all
//Load each segment into its corresponding bit plane.
_fmemcpy((fbyte)0xA0000000L,(void far*)(buffer_base+(i*0x10000000L)),size);
Code: Select all
_fmemcpy((fbyte) MK_FP(0xA000, 0), (void far*)MK_FP(buffer_seg, buffer_offset),size);
Re: 640x480x16 double buffer
This code is an attempt to make BSAVE BLOAD like QBASIC instruction
in addition to use memory instead of disk
in addition to use memory instead of disk
Distance doesn't make you any smaller,
but it does make you part of a larger picture.
but it does make you part of a larger picture.
Re: 640x480x16 double buffer
anyway i need some things to kill flicker in screen mode 0x12.
I think this screen mode or VESA mode isn't look like famous screen 0x13
I think this screen mode or VESA mode isn't look like famous screen 0x13
Distance doesn't make you any smaller,
but it does make you part of a larger picture.
but it does make you part of a larger picture.
Re: 640x480x16 double buffer
Hi,
The code goes something like this:
There's 2 problems here:
To avoid the second problem (and to reduce the time spend in the vertical retrace IRQ handler, if used) it's possible to use page flipping. The idea is that you use two areas in video display memory - an "active" area that the video card is displaying and a "work" area that you can modify without worrying much about (because it isn't being displayed). When you're ready to display the next frame it's already in display memory, and all you do is reprogram the VGA's "Start Address High Register" and "Start Address Low Register" so that the "work" area becomes the "active" area and the "active" area becomes the "work" area. This method requires more video display memory, but all modern video cards will have enough video display memory anyway. Another option would be to use dirty rectangles or some other way to avoid updating parts of video display memory that didn't change since last time.
You could also combine all of the above. For example, you draw data into your buffer in RAM (while keeping track of which areas were modified), and when you're ready you blit areas that did change from your buffer in RAM to the "work" buffer in video display memory, and then your (real or emulated) vertical retrace IRQ does a "page flip" during the next vertical retrace to make the new frame visible.
Of course all of this may be overkill - the extra complexity may or may not be worth the hassle...
Cheers,
Brendan
Before you blit the buffer to display memory, you could wait for vertical retrace to start. Note: "vertical retrace" is the time it takes the video card's signal to go from the bottom right corner of the screen to the top left corner of the screen; where the video isn't using video display memory (and where you can change video display memory without worrying about half a frame being displayed, or sheering effects, or flicker).AhmadTayseerDajani wrote:anyway i need some things to kill flicker in screen mode 0x12.
The code goes something like this:
Code: Select all
mov dx, 0x03DA ;dl = VGA misc register #1
.l1: in al, dl ;al = value from VGA misc register #1
test al, 8 ;Is the "retrace not in progress" bit set?
jnz .l1 ; yes, wait until the retrace isn't in progress
.l2: in al, dl ;al = value from VGA misc register #1
test al, 8 ;Is the "retrace not in progress" bit set?
jnz .l2 ; no, wait until the retrace is in progress
- It can waste a lot of CPU time. The retrace would happen 60 times per second for standard 640 * 480 VGA mode, so you could waste up to 16.66 ms of CPU time while you're waiting for the retrace to start, which adds up to millions of cycles for modern computers.
- The blit may be too slow to update all 4 planes before the retrace ends (especially on old/slow computers). In this case you'd get flicker even though you are waiting for retrace to start.
To avoid the second problem (and to reduce the time spend in the vertical retrace IRQ handler, if used) it's possible to use page flipping. The idea is that you use two areas in video display memory - an "active" area that the video card is displaying and a "work" area that you can modify without worrying much about (because it isn't being displayed). When you're ready to display the next frame it's already in display memory, and all you do is reprogram the VGA's "Start Address High Register" and "Start Address Low Register" so that the "work" area becomes the "active" area and the "active" area becomes the "work" area. This method requires more video display memory, but all modern video cards will have enough video display memory anyway. Another option would be to use dirty rectangles or some other way to avoid updating parts of video display memory that didn't change since last time.
You could also combine all of the above. For example, you draw data into your buffer in RAM (while keeping track of which areas were modified), and when you're ready you blit areas that did change from your buffer in RAM to the "work" buffer in video display memory, and then your (real or emulated) vertical retrace IRQ does a "page flip" during the next vertical retrace to make the new frame visible.
Of course all of this may be overkill - the extra complexity may or may not be worth the hassle...
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.
Re: 640x480x16 double buffer
while(1){
cout<<"Thank you very much Brendan for worthy information"<<endl;
}
cout<<"Thank you very much Brendan for worthy information"<<endl;
}
Distance doesn't make you any smaller,
but it does make you part of a larger picture.
but it does make you part of a larger picture.