Page 1 of 1
Scrolling
Posted: Sun Aug 24, 2008 4:08 am
by System123
I recently came across a problem in my console. My scroll algorithm does not work. It just lets the new data overwrite the old data without moving the old data up a line. Both algorithms give me the same problem.
Algorithm 1:
Code: Select all
procedure Scroll;
var
i : byte;
begin
if CursorPosY >= 24 then
begin
Move((VidMem+160)^,VidMem^,24*160);
// Empty last line
FillWord((VidMem+23*160)^,160,Blank);
CursorPosY := 23;
CursorPosX := 0;
end;
end;
Algorithm 2:
Code: Select all
procedure Scroll;
var
i : byte;
begin
if CursorPosY >= 24 then
begin
for i := 0 to 24*160 do
VidMem[i] := VidMem[i+80];
for i := 23*160 to 24*160 do
VidMem[i] := char($20);
CursorPosY := 23;
CursorPosX := 0;
end;
end;
Re: Scrolling
Posted: Sun Aug 24, 2008 5:02 am
by ru2aqare
System123 wrote:I recently came across a problem in my console. My scroll algorithm does not work. It just lets the new data overwrite the old data without moving the old data up a line. Both algorithms give me the same problem.
Algorithm 1:
Code: Select all
procedure Scroll;
var
i : byte;
begin
if CursorPosY >= 24 then
begin
Move((VidMem+160)^,VidMem^,24*160);
// Empty last line
FillWord((VidMem+23*160)^,160,Blank);
CursorPosY := 23;
CursorPosX := 0;
end;
end;
Algorithm 2:
Code: Select all
procedure Scroll;
var
i : byte;
begin
if CursorPosY >= 24 then
begin
for i := 0 to 24*160 do
VidMem[i] := VidMem[i+80];
for i := 23*160 to 24*160 do
VidMem[i] := char($20);
CursorPosY := 23;
CursorPosX := 0;
end;
end;
Your algorithm #2 is definitely buggy:
should be
as one line on the 80x25 text screen occupies 160 bytes.
Code: Select all
for i := 23*160 to 24*160 do
VidMem[i] := char($20);
may also incorrect, because it clears the line with a black-on-green background spaces. It should be
Code: Select all
for i := 23*80 to 24*80 do
begin
VidMem[2*i+0] := char($20); { space}
VidMem[2*i+1] := $07; { attribute associated with character cell }
end;
Also there may be a bug in your algorithm #1:
Code: Select all
FillWord((VidMem+23*160)^,160,Blank);
If this procedure fills a memory area with words, then you need to fill 80 words only, not 160.
Also I personally would not reset the cursor X coordinate to zero, as the procedure should only scroll the screen. Resetting the cursor X position besides scrolling the screen would in my book be a side-effect.
Re: Scrolling
Posted: Sun Aug 24, 2008 1:44 pm
by dr_evil
This code might crash under VirtualPC.
move and/or fillword, filldword, ... try to use MMX to accelerate the operations. But VirtualPC's video memory is not aligned - therefore the functions could crash under VPC with a not-aligned exception. Just use a loop to avoid this problem.
Re: Scrolling
Posted: Sun Aug 24, 2008 2:56 pm
by Laksen
dr_evil, they would only crash if the implementations of the functions are actually using mmx instructions, which you would never do if you use them in a kernel. If you just copied the RTL from the standard implementation, then I would very much recommend you to use the generic functions instead of the i386 optimized functions