[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]

    {
      Since it looks like things are moving quite slowly here, I thought I'd
    post a text viewer that I wrote. Actually, A guy named Jon Merkel
    posted the original code that showed me how to smoothly scroll text. I
    just modified it to read files and keep track of where in the file it's
    at and stuff. I was going to make it read straight binary files so it
    would display all those extended ascii characters, but I figured it'd
    be a lot easier this way.
        Basically, it just reads the file 102 lines at a time. It starts out
    by filling the video memory with 204 lines of text and then updates it
    as needed. I guess there really isn't a fliesize limit.. Actually there
    would be   ummm  FilePs is a longint so it'd be 2147483647*80. Well,
    by the time you got that size file, it'd take a couple years to scroll
    becuase my method of seeking a text file leaves MUCH to be desired!
        Please modify this and make it faster! I didn't spend much time on it,
    and if i worked on it again, I'd probably load more than 204 lines of the
    file into some temp array and then just use MOVE to transfer that data
    to video memory.
        Anyways, do what you wish, but please don't dis me for bad code becuase
    as I said, I didn't spend much time on this.. just thought you'd all like
    to see it.. Enjoy!
     BTW, I already posted this in the FIDO pascal echo.
    }
    {----------------------------------------------------------------------------}
    program View;
    const
        DownKey = $50;                          { Scan code for the down arrow }
        UpKey   = $48;                          { Scan code for the up arrow   }
        EscKey  = $1;                           { Scan code for the escape key }
        done: boolean = false;
        start: integer = 0;
        velocity: integer = 0;

    Var
      Tfile : text;                           {Text File to read in duh!}
      FilePs,OldPs : LongInt;                 {File Positions maybe?}
      StLoad,EndFile : Boolean;               {Tell if at end or start of file}
      character: record ch:char; attr:byte; end;   {Jon's Record GLOBALLY}

    Procedure Error(num:byte);                {Returns error if used wrong}
     Begin
       Writeln;
       Case Num of
         1 : Writeln('Error 1 !  Proper usage is:  VIEW <FileName>');
         2 : Writeln('Invalid File! Be sure full name/path/ext is included.');
       End;
       Writeln;  Halt;
     End;

    procedure Initialize;                           { Initialize the program    }
    var
      j, k, offset : word;                         {counters and video offset}
      z,x          : byte;                         {Counters and stuff}
      s            : string;                       {Read file into this}
    begin
      asm mov ax,3; int 10h; end;                     { Set 80x25 text mode   }
      asm in al,21h; or al,2; out 21h,al; end;        { Disable the keyboard  }
      asm mov ax,0100h; mov cx,2000h; int 10h; end;   { Hide the cursor       }
      FillChar(mem[$B800:0], 32768, 0);               { clear video memory    }
      j:=0;  StLoad := TRUE;  FilePs := 1;
      While (j<203) and (not eof(Tfile)) do begin
        z:=1;  x:=0;  s:='';                          {Init variables}
        Readln(TFile,s);
        offset := j*160;
        character.attr := 7;
        for k := 1 to length(s) do begin
          character.ch := s[k];
          memw[$B800:offset] := word(character);  {display character and Attr}
          inc(offset, 2);
        end;
        inc(j);
      end;
      If Eof(Tfile) Then EndFile := TRUE Else EndFIle := FALSE;
      OldPs := 0; FilePs:=204;        {Init file positions}
    end;

    procedure SetScreenStart(ScanLine:word);            { MAIN PROCEDURE !!!!   }
    var
      StartAddress: word;
    begin
      StartAddress := (ScanLine div 16)*80;
      portw[$3D4] := hi(StartAddress) shl 8 + $0C;    { Set start address     }
      portw[$3D4] := lo(StartAddress) shl 8 + $0D;
      repeat until port[$3DA] and 8<>0;               { wait for retrace      }
      portw[$3D4] := (ScanLine mod 16) shl 8 + 8;     { Set start scanline    }
      repeat until port[$3DA] and 8=0;                { wait out retrace      }
    end;

    Procedure Forwards;                   {Reads next 102 lines in the file}
     Var
       s : string;      z,x : byte;            {junk}
       offset : word;                      {didn't we already go thru this one?}
     Begin
       StLoad := FALSE;                    {no longer start of file}
       Move(Mem[$B800:102*160],Mem[$B800:0],16320);

        {This procedure is done so that when we reach the end of video mem,
          we move the last half of memory to the top and load 102 more lines
          neat huh? Actually it's VERY SLow.. especially if your dealing with
          a file that's ohh say more than a meg!}
       SetScreenStart(start);
       FillChar(Mem[$b800:16320],16320,0);
       z:=0;   OldPs := FilePs-102;  {Preserve File Position in OldPs}
       While (not Eof(Tfile)) and (z<102) do Begin
         Inc(z);  Inc(FilePs);
         Readln(Tfile,s);
         offset := (z+102)*160;
         character.attr := 7;
         for x := 1 to length(s) do begin
           character.ch := s[x];
           memw[$B800:offset] := word(character);
           inc(offset, 2);
         end;
       End;
       If eof(Tfile) then EndFile := TRUE;   {We have reached the end!}
     End;

    Procedure Backwards;                   {Backs up 102 lines in file}
     Var
       s : string;        x,z : byte;
       cnt : longint;     Offset : word;
     Begin
       Move(mem[$B800:0],mem[$B800:102*160],16320);
       SetScreenStart(start);
       FillChar(Mem[$B800:0],16320,0);
       Reset(Tfile);
       cnt:=0;
       While cnt < (OldPs-102) do Begin  {slow way to seek a text file}
         inc(cnt);
         Readln(Tfile);
       End;
       Dec(FilePs,102); Dec(OldPs,102);   {get our file position right!}
       If OldPs = 0 then StLoad := TRUE;
       z:=0;                                 {De ja vu!}
       While z<102 do Begin
         Inc(z);
         Readln(Tfile,S);
         offset := (z-1)*160;
         Character.attr := 7;
         for x := 1 to length(s) do begin
           character.ch := s[x];
           memw[$B800:offset] := word(character);
           inc(offset, 2);
         end;
       End;
       For z := 1 to 102 do Readln(Tfile,s);   {get back to right position}
     End;

    {/////////////// Main Program//////////////////////////////////////////////}
    begin
        If ParamCount < 1 Then Error(1);
        Assign(Tfile,Paramstr(1));                  {load our text file}
        {$I-} Reset(Tfile);  {$I+}
        If IoResult <> 0 Then Error(2);
        Initialize;
        repeat
            case port[$60] of                               { Check keypress    }
                DownKey : inc(velocity,2);
                UpKey   : dec(velocity,2);
                EscKey  : done := true;
            end;
            inc(start, velocity);                   { update screen position    }
            if word(start) > (203-24)*16 then
                if start < 0 then begin   {Hit top}
                    If not StLoad Then Begin
                      start := (102)*16-velocity;    {kinda glitchy}
                      BackWards;
                    End Else Begin
                      Start := 0;
                      velocity := 0;
                    End;
                end
                else begin      {hit bottom}
                    If Not EndFile Then Begin
                      start := (102-25)*16+velocity;   {same as   ^^^^}
                      Forwards;
                    End Else Begin
                      start := (203-24)*16;
                      velocity := 0;
                    End;
                end;
            if velocity > 0 then dec(velocity)
            else if velocity < 0 then inc(velocity);
            SetScreenStart(start);                      { set screen position   }
        until done;
        asm in al,21h; and al,253; out 21h,al; end;         { enable keyboard   }
        asm mov ax,3; int 10h; end;                         { reset text mode   }
    end.

[Back to TEXTFILE SWAG index] [Back to Main SWAG index] [Original]