- Cleaned up some comments again

- The dirtyPages[] array overrun conditions should be really safe now
This commit is contained in:
gbeauche 2001-01-11 18:00:40 +00:00
parent 5d671689db
commit 252d602e96
2 changed files with 38 additions and 9 deletions

View File

@ -350,6 +350,39 @@ static bool Screen_fault_handler_init()
* Update display for Windowed mode and VOSF
*/
/* How can we deal with array overrun conditions ?
The state of the framebuffer pages that have been touched are maintained
in the dirtyPages[] table. That table is (pageCount + 2) bytes long.
Terminology
"Last Page" denotes the pageCount-nth page, i.e. dirtyPages[pageCount - 1].
"CLEAR Page Guard" refers to the page following the Last Page but is always
in the CLEAR state. "SET Page Guard" refers to the page following the CLEAR
Page Guard but is always in the SET state.
Rough process
The update routines must determine which pages have to blitted to the
screen. This job consists in finding the first_page that was touched.
i.e. find the next page that is SET. Then, finding how many pages were
touched starting from first_page. i.e. find the next page that is CLEAR.
Two cases
- Last Page is CLEAR: find_next_page_set() will reach the SET Page Guard
but it is beyond the valid pageCount value. Therefore, we exit from the
update routine.
- Last Page is SET: first_page equals (pageCount - 1) and
find_next_page_clear() will reach the CLEAR Page Guard. We blit the last
page to the screen. On the next iteration, page equals pageCount and
find_next_page_set() will reach the SET Page Guard. We still safely exit
from the update routine because the SET Page Guard position is greater
than pageCount.
*/
static inline void update_display_window_vosf(void)
{
int page = 0;

View File

@ -264,8 +264,6 @@ static inline int find_next_page_clear(int page)
char *match = strchr(mainBuffer.dirtyPages + page, PFLAG_CLEAR_VALUE);
return match ? match - mainBuffer.dirtyPages : mainBuffer.pageCount;
#else
// NOTE: the loop is bound to terminate because the last
// page in mainBuffer.dirtyPages[] shall be set to CLEAR
while (PFLAG_ISSET_4(page))
page += 4;
while (PFLAG_ISSET(page))
@ -945,7 +943,7 @@ bool VideoInitBuffer()
if (mainBuffer.dirtyPages != 0)
free(mainBuffer.dirtyPages);
mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 1);
mainBuffer.dirtyPages = (char *) malloc(mainBuffer.pageCount + 2);
if (mainBuffer.pageInfo != 0)
free(mainBuffer.pageInfo);
@ -956,12 +954,10 @@ bool VideoInitBuffer()
return false;
PFLAG_CLEAR_ALL;
// Make sure there is at least one page marked, so the
// loops in the update routine will terminate
// gb-- Set the last page as cleared because the update
// routine finally searches for a page that was not touched
// Safety net to insure the loops in the update routines will terminate
// See a discussion in <video_vosf.h> for further details
PFLAG_CLEAR(mainBuffer.pageCount);
PFLAG_SET(mainBuffer.pageCount+1);
uint32 a = 0;
for (int i = 0; i < mainBuffer.pageCount; i++) {
@ -1955,7 +1951,7 @@ static void update_display_static(void)
// We suggest the compiler to inline the next two functions so that it
// may specialise the code according to the current screen depth and
// display type. A clever compiler would that job by itself though...
// display type. A clever compiler would do that job by itself though...
// NOTE: update_display_vosf is inlined too