Scrolling

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Scrolling

Post 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;
Gizmic OS
Currently - Busy with FAT12 driver and VFS
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: Scrolling

Post 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:

Code: Select all

      VidMem[i] := VidMem[i+80];
should be

Code: Select all

      VidMem[i] := VidMem[i+160];
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.
dr_evil
Member
Member
Posts: 34
Joined: Mon Dec 20, 2004 12:00 am

Re: Scrolling

Post 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.
Laksen
Member
Member
Posts: 140
Joined: Fri Nov 09, 2007 3:30 am
Location: Aalborg, Denmark

Re: Scrolling

Post 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
http://j-software.dk | JPasKernel - My Object Pascal kernel
Post Reply