Browse Source

+ initial implementation of a win16 crt unit, implemented on top of the video unit

git-svn-id: trunk@31863 -
nickysn 10 years ago
parent
commit
9b0f509242
3 changed files with 538 additions and 2 deletions
  1. 1 0
      .gitattributes
  2. 3 2
      packages/rtl-console/fpmake.pp
  3. 534 0
      packages/rtl-console/src/win16/crt.pp

+ 1 - 0
.gitattributes

@@ -6807,6 +6807,7 @@ packages/rtl-console/src/win/keyboard.pp svneol=native#text/plain
 packages/rtl-console/src/win/mouse.pp svneol=native#text/plain
 packages/rtl-console/src/win/mouse.pp svneol=native#text/plain
 packages/rtl-console/src/win/video.pp svneol=native#text/plain
 packages/rtl-console/src/win/video.pp svneol=native#text/plain
 packages/rtl-console/src/win/winevent.pp svneol=native#text/plain
 packages/rtl-console/src/win/winevent.pp svneol=native#text/plain
+packages/rtl-console/src/win16/crt.pp svneol=native#text/plain
 packages/rtl-console/src/win16/video.pp svneol=native#text/plain
 packages/rtl-console/src/win16/video.pp svneol=native#text/plain
 packages/rtl-extra/Makefile svneol=native#text/plain
 packages/rtl-extra/Makefile svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc svneol=native#text/plain

+ 3 - 2
packages/rtl-console/fpmake.pp

@@ -16,13 +16,13 @@ Const
   KVMAll       = [emx,go32v2,netware,netwlibc,os2,win32,win64]+UnixLikes+AllAmigaLikeOSes;
   KVMAll       = [emx,go32v2,netware,netwlibc,os2,win32,win64]+UnixLikes+AllAmigaLikeOSes;
   
   
   // all full KVMers have crt too, except Amigalikes
   // all full KVMers have crt too, except Amigalikes
-  CrtOSes      = KVMALL+[msdos,WatCom]-[aros,morphos];
+  CrtOSes      = KVMALL+[msdos,WatCom,win16]-[aros,morphos];
   KbdOSes      = KVMALL+[msdos];
   KbdOSes      = KVMALL+[msdos];
   VideoOSes    = KVMALL+[win16];
   VideoOSes    = KVMALL+[win16];
   MouseOSes    = KVMALL;
   MouseOSes    = KVMALL;
   TerminfoOSes = UnixLikes-[beos,haiku];
   TerminfoOSes = UnixLikes-[beos,haiku];
 
 
-  rtl_consoleOSes =KVMALL+CrtOSes+TermInfoOSes+[win16];
+  rtl_consoleOSes =KVMALL+CrtOSes+TermInfoOSes;
 
 
 // Amiga has a crt in its RTL dir, but it is commented in the makefile
 // Amiga has a crt in its RTL dir, but it is commented in the makefile
 
 
@@ -99,6 +99,7 @@ begin
        AddInclude('crth.inc');
        AddInclude('crth.inc');
        AddInclude('crt.inc');
        AddInclude('crt.inc');
        AddInclude('nwsys.inc',[netware]);
        AddInclude('nwsys.inc',[netware]);
+       AddUnit   ('video',[win16]);
      end;
      end;
 
 
     T:=P.Targets.AddUnit('vesamode.pp',[go32v2]);
     T:=P.Targets.AddUnit('vesamode.pp',[go32v2]);

+ 534 - 0
packages/rtl-console/src/win16/crt.pp

@@ -0,0 +1,534 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2015 by the Free Pascal development team.
+
+    Borland Pascal 7 Compatible CRT Unit - Win16 implementation
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit crt;
+
+{$GOTO on}
+
+interface
+
+{$i crth.inc}
+
+Var
+  ScreenWidth,
+  ScreenHeight : word;
+
+implementation
+
+uses
+  video;
+
+{****************************************************************************
+                           Low level Routines
+****************************************************************************}
+
+function GetScreenHeight : word;
+begin
+  getscreenheight:=video.ScreenHeight;
+end;
+
+
+function GetScreenWidth : word;
+begin
+  getscreenwidth:=video.ScreenWidth;
+end;
+
+
+procedure SetScreenCursor(x,y : smallint);
+begin
+  video.SetCursorPos(x-1,y-1);
+end;
+
+
+procedure GetScreenCursor(var x,y : smallint);
+begin
+  x:=video.CursorX+1;
+  y:=video.CursorY+1;
+end;
+
+
+{****************************************************************************
+                              Helper Routines
+****************************************************************************}
+
+var
+  WinMin: packed record
+    X, Y: Byte;
+  end absolute WindMin;
+
+  WinMax: packed record
+    X, Y: Byte;
+  end absolute WindMax;
+
+
+Function FullWin:boolean;
+{
+  Full Screen 80x25? Window(1,1,80,25) is used, allows faster routines
+}
+begin
+  FullWin:=(WinMin.X=0) and (WinMin.Y=0) and
+           (word(WinMax.X+1)=ScreenWidth) and (word(WinMax.Y+1)=ScreenHeight);
+end;
+
+
+{****************************************************************************
+                             Public Crt Functions
+****************************************************************************}
+
+
+procedure textmode (Mode: word);
+begin
+end;
+
+
+Procedure TextColor(Color: Byte);
+{
+  Switch foregroundcolor
+}
+Begin
+  TextAttr:=(Color and $f) or (TextAttr and $70);
+  If (Color>15) Then TextAttr:=TextAttr Or Blink;
+End;
+
+
+
+Procedure TextBackground(Color: Byte);
+{
+  Switch backgroundcolor
+}
+Begin
+  TextAttr:=((Color shl 4) and ($f0 and not Blink)) or (TextAttr and ($0f OR Blink) );
+End;
+
+
+
+Procedure HighVideo;
+{
+  Set highlighted output.
+}
+Begin
+  TextColor(TextAttr Or $08);
+End;
+
+
+
+Procedure LowVideo;
+{
+  Set normal output
+}
+Begin
+  TextColor(TextAttr And $77);
+End;
+
+
+
+Procedure NormVideo;
+{
+  Set normal back and foregroundcolors.
+}
+Begin
+  TextColor(7);
+  TextBackGround(0);
+End;
+
+
+Procedure GotoXy(X: tcrtcoord; Y: tcrtcoord);
+{
+  Go to coordinates X,Y in the current window.
+}
+Begin
+  If (X>0) and (X<=WinMax.X- WinMin.X+1) and
+     (Y>0) and (Y<=WinMax.Y-WinMin.Y+1) Then
+   Begin
+     Inc(X,WinMin.X);
+     Inc(Y,WinMin.Y);
+     SetScreenCursor(x,y);
+   End;
+End;
+
+
+Procedure Window(X1, Y1, X2, Y2: Byte);
+{
+  Set screen window to the specified coordinates.
+}
+Begin
+  if (X1>X2) or (word(X2)>ScreenWidth) or
+     (Y1>Y2) or (word(Y2)>ScreenHeight) then
+   exit;
+  WindMin:=((Y1-1) Shl 8)+(X1-1);
+  WindMax:=((Y2-1) Shl 8)+(X2-1);
+  GoToXY(1,1);
+End;
+
+
+Procedure ClrScr;
+{
+  Clear the current window, and set the cursor on 1,1
+}
+var
+  fil : word;
+  y   : word;
+begin
+  fil:=32 or (textattr shl 8);
+  if FullWin then
+    FillWord(VideoBuf^,ScreenHeight*ScreenWidth,fil)
+  else
+    begin
+      for y:=WinMin.Y to WinMax.Y do
+        FillWord(VideoBuf^[y*ScreenWidth+word(WinMin.X)],WinMax.X-WinMin.X+1,fil);
+    end;
+  UpdateScreen(false);
+  Gotoxy(1,1);
+end;
+
+
+Procedure ClrEol;
+{
+  Clear from current position to end of line.
+}
+var
+  x,y : smallint;
+  fil : word;
+Begin
+  GetScreenCursor(x,y);
+  fil:=32 or (textattr shl 8);
+  if x<=(WinMax.X+1) then
+    begin
+      FillWord(VideoBuf^[(word(y-1)*ScreenWidth+word(x-1))],WinMax.X-x+2,fil);
+      UpdateScreen(false);
+    end;
+End;
+
+
+
+Function WhereX: tcrtcoord;
+{
+  Return current X-position of cursor.
+}
+var
+  x,y : smallint;
+Begin
+  GetScreenCursor(x,y);
+  WhereX:=x-WinMin.X;
+End;
+
+
+
+Function WhereY: tcrtcoord;
+{
+  Return current Y-position of cursor.
+}
+var
+  x,y : smallint;
+Begin
+  GetScreenCursor(x,y);
+  WhereY:=y-WinMin.Y;
+End;
+
+
+{*************************************************************************
+                            KeyBoard
+*************************************************************************}
+
+function readkey : char;
+begin
+end;
+
+
+function keypressed : boolean;
+begin
+end;
+
+
+{*************************************************************************
+                                   Delay
+*************************************************************************}
+
+procedure Delay(MS: Word);
+begin
+end;
+
+
+procedure sound(hz : word);
+begin
+end;
+
+
+procedure nosound;
+begin
+end;
+
+
+
+{****************************************************************************
+                          HighLevel Crt Functions
+****************************************************************************}
+
+procedure removeline(y : word);
+var
+  fil : word;
+begin
+  fil:=32 or (textattr shl 8);
+  y:=WinMin.Y+y;
+  While (y<=WinMax.Y) do
+    begin
+      Move(VideoBuf^[(y*ScreenWidth+word(WinMin.X))],
+           VideoBuf^[((y-1)*ScreenWidth+word(WinMin.X))],(WinMax.X-WinMin.X+1)*2);
+      inc(y);
+    end;
+  FillWord(VideoBuf^[(word(WinMax.Y)*ScreenWidth+word(WinMin.X))],(WinMax.X-WinMin.X+1),fil);
+end;
+
+
+procedure delline;
+begin
+  removeline(wherey);
+  UpdateScreen(false);
+end;
+
+
+procedure insline;
+var
+  my,y : smallint;
+  fil : word;
+begin
+  fil:=32 or (textattr shl 8);
+  y:=WhereY;
+  my:=WinMax.Y-WinMin.Y;
+  while (my>=y) do
+    begin
+      Move(VideoBuf^[(word(WinMin.Y+my-1)*ScreenWidth+word(WinMin.X))],
+           VideoBuf^[(word(WinMin.Y+my)*ScreenWidth+word(WinMin.X))],(WinMax.X-WinMin.X+1)*2);
+      dec(my);
+    end;
+  FillWord(VideoBuf^[(word(WinMin.Y+y-1)*ScreenWidth+word(WinMin.X))],(WinMax.X-WinMin.X+1),fil);
+  UpdateScreen(false);
+end;
+
+
+
+
+{****************************************************************************
+                             Extra Crt Functions
+****************************************************************************}
+
+procedure cursoron;
+begin
+  SetCursorType(crUnderLine);
+end;
+
+
+procedure cursoroff;
+begin
+  SetCursorType(crHidden);
+end;
+
+
+procedure cursorbig;
+begin
+  SetCursorType(crBlock);
+end;
+
+
+{*****************************************************************************
+                          Read and Write routines
+*****************************************************************************}
+
+var
+  CurrX,CurrY : smallint;
+
+Procedure WriteChar(c:char);
+begin
+  case c of
+   #10 : inc(CurrY);
+   #13 : CurrX:=WinMin.X+1;
+    #8 : begin
+           if CurrX>(WinMin.X+1) then
+            dec(CurrX);
+         end;
+    #7 : begin { beep }
+//           regs.dl:=7;
+//           regs.ah:=2;
+//           intr($21,regs);
+         end;
+  else
+   begin
+     VideoBuf^[word(CurrY-1)*ScreenWidth+word(CurrX-1)]:=(textattr shl 8) or byte(c);
+     inc(CurrX);
+   end;
+  end;
+  if CurrX>(WinMax.X+1) then
+   begin
+     CurrX:=(WinMin.X+1);
+     inc(CurrY);
+   end;
+  while CurrY>(WinMax.Y+1) do
+   begin
+     removeline(1);
+     dec(CurrY);
+   end;
+end;
+
+
+Procedure CrtWrite(var f : textrec);
+var
+  i : smallint;
+begin
+  GetScreenCursor(CurrX,CurrY);
+  for i:=0 to f.bufpos-1 do
+   WriteChar(f.buffer[i]);
+  SetScreenCursor(CurrX,CurrY);
+  f.bufpos:=0;
+  UpdateScreen(false);
+end;
+
+
+Procedure CrtRead(Var F: TextRec);
+
+  procedure BackSpace;
+  begin
+    if (f.bufpos>0) and (f.bufpos=f.bufend) then
+     begin
+       WriteChar(#8);
+       WriteChar(' ');
+       WriteChar(#8);
+       dec(f.bufpos);
+       dec(f.bufend);
+     end;
+  end;
+
+var
+  ch : Char;
+Begin
+  GetScreenCursor(CurrX,CurrY);
+  f.bufpos:=0;
+  f.bufend:=0;
+  repeat
+    if f.bufpos>f.bufend then
+     f.bufend:=f.bufpos;
+    SetScreenCursor(CurrX,CurrY);
+    ch:=readkey;
+    case ch of
+    #0 : case readkey of
+          #71 : while f.bufpos>0 do
+                 begin
+                   dec(f.bufpos);
+                   WriteChar(#8);
+                 end;
+          #75 : if f.bufpos>0 then
+                 begin
+                   dec(f.bufpos);
+                   WriteChar(#8);
+                 end;
+          #77 : if f.bufpos<f.bufend then
+                 begin
+                   WriteChar(f.bufptr^[f.bufpos]);
+                   inc(f.bufpos);
+                 end;
+          #79 : while f.bufpos<f.bufend do
+                 begin
+                   WriteChar(f.bufptr^[f.bufpos]);
+                   inc(f.bufpos);
+                 end;
+         end;
+    ^S,
+    #8 : BackSpace;
+    ^Y,
+   #27 : begin
+           while f.bufpos<f.bufend do begin
+            WriteChar(f.bufptr^[f.bufpos]);
+            inc(f.bufpos);
+           end;
+           while f.bufend>0 do
+            BackSpace;
+         end;
+   #13 : begin
+           WriteChar(#13);
+           WriteChar(#10);
+           f.bufptr^[f.bufend]:=#13;
+           f.bufptr^[f.bufend+1]:=#10;
+           inc(f.bufend,2);
+           break;
+         end;
+   #26 : if CheckEOF then
+          begin
+            f.bufptr^[f.bufend]:=#26;
+            inc(f.bufend);
+            break;
+          end;
+    else
+     begin
+       if f.bufpos<f.bufsize-2 then
+        begin
+          f.buffer[f.bufpos]:=ch;
+          inc(f.bufpos);
+          WriteChar(ch);
+        end;
+     end;
+    end;
+  until false;
+  f.bufpos:=0;
+  SetScreenCursor(CurrX,CurrY);
+End;
+
+
+Procedure CrtReturn(Var F: TextRec);
+Begin
+end;
+
+
+Procedure CrtClose(Var F: TextRec);
+Begin
+  F.Mode:=fmClosed;
+End;
+
+
+Procedure CrtOpen(Var F: TextRec);
+Begin
+  If F.Mode=fmOutput Then
+   begin
+     TextRec(F).InOutFunc:=@CrtWrite;
+     TextRec(F).FlushFunc:=@CrtWrite;
+   end
+  Else
+   begin
+     F.Mode:=fmInput;
+     TextRec(F).InOutFunc:=@CrtRead;
+     TextRec(F).FlushFunc:=@CrtReturn;
+   end;
+  TextRec(F).CloseFunc:=@CrtClose;
+End;
+
+
+procedure AssignCrt(var F: Text);
+begin
+  Assign(F,'');
+  TextRec(F).OpenFunc:=@CrtOpen;
+end;
+
+begin
+  InitVideo;
+{ Load startup values }
+  ScreenWidth:=GetScreenWidth;
+  ScreenHeight:=GetScreenHeight;
+  WindMax:=(ScreenWidth-1) or ((ScreenHeight-1) shl 8);
+  TextAttr:=$07;
+{ Redirect the standard output }
+  assigncrt(Output);
+  Rewrite(Output);
+  TextRec(Output).Handle:=StdOutputHandle;
+  assigncrt(Input);
+  Reset(Input);
+  TextRec(Input).Handle:=StdInputHandle;
+end.