home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug077.arc / SCRNHND.FWD < prev    next >
Text File  |  1979-12-31  |  11KB  |  502 lines

  1. Procedure SCNSetUpColRAM;
  2. Var B : Byte;
  3. Begin
  4.   B := Port[ COLPORT ];
  5.   B := B or $40;
  6.   Port[ COLPORT ] := B;
  7. End;
  8.  
  9. Procedure SCNSetUpPCGRam;
  10. Var b : Byte;
  11. Begin
  12.   B := Port[ COLPORT ];
  13.   B := B and $6F;
  14.   Port[ ColPort ] := B;
  15. End;
  16.  
  17. Procedure SetWindowColours;
  18. Var
  19.   c,s,EndN,i : integer;
  20. Begin
  21.   If not SCNColour then exit;
  22.   SCNSetUpColRAM;
  23.   C := 16*BCol + FCol;
  24.   S := ColSt + 80 * ( SCNYStart - 1 );
  25.   EndN := ColSt + 80 * ( SCNYEnd - 1 );
  26.   While S <= EndN do
  27.     Begin
  28.       For i:= ( ScnXstart - 1 ) to ( SCNXEnd - 1 ) do Mem[ S + i ] := C;
  29.       S := S + 80;
  30.     End;
  31.   SCNSetUpPCGRam;
  32. end;
  33.  
  34. Procedure SetUpCols;
  35.  
  36. Var i,
  37.     S,
  38.     EndN : integer;
  39.     C   : Byte;
  40. Begin
  41.   If not SCNColour then exit;
  42.   x1 := Pred( x1 + SCNXStart );
  43.   x2 := Pred( x2 + SCNXStart );
  44.   y1 := Pred( y1 + SCNYStart );
  45.   y2 := Pred( y2 + SCNYStart );
  46.   If ( X1 > X2 ) or ( Y1 > Y2 ) or ( x2 > 80 ) or ( y2 > 25 ) then Exit;
  47.   SCNSetUpColRAM;
  48.   C := 16*BCol + FCol;
  49.   S := ColSt + 80 * ( Y1 - 1 );
  50.   EndN := ColSt + 80 * ( Y2 - 1 );
  51.   While S <= EndN do
  52.     Begin
  53.       For i:= ( X1 - 1 ) to ( X2 - 1 ) do Mem[ S + i ] := C;
  54.       S := S + 80;
  55.     End;
  56.   SCNSetUpPCGRam;
  57. End;
  58.  
  59. Procedure SCNTestColour;
  60. Var a,b : byte;
  61. Begin
  62.   B := mem[ $F800 ];
  63.   Mem[ $F800 ] := 0;
  64.   SCNSetUpColRam;
  65.   A := mem[ $F800 ];
  66.   Mem[ $F800 ] := $FF;
  67.   SCNSetUpPCGRam;
  68.   SCNColour := Mem[ $F800 ] = 0;
  69.   mem[ $F800 ] := B;
  70.   If SCNColour then
  71.     begin
  72.       SCNSetUpColRam;
  73.       Mem[ $F800 ] := A;
  74.       SCNSetUpPCGRam;
  75.     end;
  76. End;
  77.  
  78. Function SCNReadPort;
  79. Begin
  80.   Port[ SelectPort ] := PortNo;
  81.   SCNReadPort := Port[ DataPort ];
  82. End;
  83.  
  84. Procedure SCNSetPort;
  85. Begin
  86.   Port[ SelectPort ] := PortNo;
  87.   Port[ DataPort ] := Value;
  88. End;
  89.  
  90. Procedure SCNInitSizes;
  91. Begin
  92.   SCNXStart := 1;
  93.   SCNYStart := 1;
  94.   SCNXEnd := 80;
  95.   SCNYEnd := 24;
  96. End;
  97.  
  98. Procedure TurnOnCurs;
  99. Var B : byte;
  100. Begin
  101.   B := SCNStartLine;
  102.   If SCNFlashing then B := B or $60;
  103.   SCNSetPort( 10 , B );
  104.   SCNSetPort( 11 , SCNEndLine );
  105. End;
  106.  
  107. Procedure TurnOffCurs;
  108. Var B : byte;
  109. Begin
  110.   B := $20;
  111.   SCNSetPort( 10 , B );
  112. End;
  113.  
  114. Function ActXStart;
  115. Begin
  116.   If SCNBorderMode then
  117.     ActXStart := Succ( SCNXStart )
  118.   Else
  119.     ActXStart := SCNXStart;
  120. End;
  121.  
  122. Function ActXEnd;
  123. Begin
  124.   If SCNBorderMode then
  125.     ActXEnd := Pred( SCNXEnd )
  126.   Else
  127.     ActXEnd := SCNXEnd;
  128. End;
  129.  
  130. Function ActYStart;
  131. Begin
  132.   If SCNBorderMode then
  133.     ActYStart := Succ( SCNYStart )
  134.   Else
  135.     ActYStart := SCNYStart;
  136. End;
  137.  
  138. Function ActYEnd;
  139. Begin
  140.   If SCNBorderMode then
  141.     ActYEnd := Pred( SCNYEnd )
  142.   Else
  143.     ActYEnd := SCNYEnd;
  144. End;
  145.  
  146. Procedure PutCurs;
  147. Var Val : integer;
  148. Begin
  149.   SCNXPos := X;
  150.   SCNYPos := Y;
  151.   Val := $2000 or( Pred( RYPos ) * 80 + Pred( RXPos ) );
  152.   SCNSetPort( 14 , Hi( Val ) );
  153.   SCNSetPort( 15 , Lo( Val ) );
  154. End;
  155.  
  156. Procedure ScreenInit;
  157. Begin
  158.   SCNTestColour;
  159.   SCNFirstWindow := Nil;
  160.   SCNRangeCheck := True;
  161.   SCNInverse := False;
  162.   SCNFlashing := True;
  163.   SCNBorderMode := False;
  164.   SCNStartLine := 0;
  165.   SCNEndLine := 11;
  166.   SCNInitSizes;
  167.   PutCurs( 1,1 );
  168.   TurnOnCurs;
  169.   Gotoxy( 1,1 );
  170. End;
  171.  
  172. Procedure ClearScreen;
  173. Var y,
  174.     Len,
  175.     Start : byte;
  176. Begin
  177.   Start := ActXStart;
  178.   Len := Succ( ActXEnd - Start );
  179.   If SCNBorderMode then
  180.       PutCurs( 2,2 )
  181.   Else
  182.       PutCurs( 1,1 );
  183.   For y:= ActYStart to ACTYEnd do
  184.     FillChar( ScnScreen[ Y , Start ] , Len , ' ' );
  185. End;
  186.  
  187. Procedure ClearEOL;
  188. Var Len : byte;
  189. Begin
  190.   Len := Succ( ActXEnd - RXPos );
  191.   If Not SCNBorderMode then Len := Succ( Len );
  192.   FillChar( ScnScreen[ RYPos , RXPos ] , Len , ' ' );
  193. End;
  194.  
  195. Procedure InsertLine;
  196. Var
  197.   Y,
  198.   Len,
  199.   XStart : byte;
  200. Begin
  201.   XStart := ActXStart;
  202.   Len := Succ( ActXEnd - ActXStart );
  203.   For y := Pred( ActYEnd ) downto RYPos do
  204.       Move( ScnScreen[ y , XStart ] , ScnScreen[ Succ(y) , XStart ] , Len );
  205.   FillChar( ScnScreen[ RYPos , XStart ] , Len , ' ' );
  206. End;
  207.  
  208. Procedure DeleteLine;
  209. Var y,
  210.     Len,
  211.     XStart : byte;
  212. Begin
  213.   XStart := ACTXStart;
  214.   Len := Succ( ActXEnd - XStart );
  215.   For y := Succ( RYPos ) to ActYEnd do
  216.     Move( ScnScreen[ y , XStart ] , ScnScreen[ Pred( y ) , XStart ] , Len );
  217.   FillChar( ScnScreen[ ActYEnd , XStart ] , Len , ' ' );
  218. End;
  219.  
  220. Procedure InsertChar;
  221. Var YPos,
  222.     x : byte;
  223. Begin
  224.   YPos := RYPos;
  225.   For x := Pred( ActXEnd ) downto RXPos do ScnScreen[ YPos , Succ( X ) ] := ScnScreen[ YPos , X ];
  226.   If RXPos <= ActXEnd then ScnScreen[ YPos , RXpos ] := ' ';
  227. End;
  228.  
  229. Procedure DeleteChar;
  230. Var YPos,
  231.     X : byte;
  232. Begin
  233.   YPos := RYPos;
  234.   For x := Succ( RXPos ) to ActXEnd do ScnScreen[ YPos , Pred( X ) ] := ScnScreen[ YPos , x ];
  235.   If RXPos <= ActXEnd then ScnScreen[ YPos , ActXEnd ] := ' ';
  236. End;
  237.  
  238. Procedure DoWrite;
  239. Var Len,
  240.     XStart,
  241.     YStart,
  242.     XEnd,
  243.     YEnd : byte;
  244.     Ch : char;
  245. Begin
  246.   If SCNBorderMode then
  247.     Begin
  248.       XStart := 2;
  249.       YStart := 2;
  250.       XEnd   := SCNXEnd - SCNXStart;
  251.       YEnd   := SCNYEnd - SCNYStart;
  252.     End
  253.   Else
  254.     Begin
  255.       XStart := 1;
  256.       YStart := 1;
  257.       XEnd   := Succ( SCNXEnd - SCNXStart );
  258.       YEnd   := Succ( SCNYEnd - SCNYStart );
  259.     End;
  260.   Len := 1;
  261.   While Len <= Length( Str ) do
  262.     Begin
  263.       Ch := Str[ Len ];
  264.       If Ch = ^H then
  265.           SCNXPos := Pred( SCNXPos )
  266.       Else
  267.         If Ch = ^M then
  268.             SCNXPos := XStart
  269.         Else
  270.           If Ch = ^J then
  271.               SCNYPos := Succ( SCNYPos )
  272.           Else
  273.             If Ch = ^G then
  274.               Write( ^G )
  275.             Else
  276.              Begin   {Print the char}
  277.                If SCNInverse then Ch := Chr( Ord( Ch ) or $80 );
  278.                ScnScreen[ RYPos , RXPos ] := Ch;
  279.                SCNXPos := Succ( SCNXPos );
  280.              End;
  281.       If SCNRangeCheck then
  282.         Begin
  283.           If SCNXPos < XStart then
  284.             Begin
  285.               SCNXPos := XEnd;
  286.               SCNYPos := Pred( SCNYPos );
  287.             End;
  288.           If SCNXPos > XEnd then
  289.             Begin
  290.               SCNYPos := Succ( SCNYPos );
  291.               SCNXPos := XStart;
  292.             End;
  293.           If SCNYPos < YStart then
  294.             Begin
  295.               SCNYPos := YStart;
  296.               SCNXPos := XStart;
  297.             End;
  298.           If SCNYPos > YEnd then
  299.             Begin
  300.               SCNYPos := YEnd;
  301.               SCNXPos := XStart;
  302.             End;
  303.         End;
  304.       Len := Succ( Len );
  305.     End;
  306.   PutCurs( SCNXPos , SCNYPos );
  307. End;
  308.  
  309. Procedure DoWriteln;
  310. Begin
  311.   DoWrite( Str + ^J + ^M );
  312. End;
  313.  
  314. Procedure NMDoWrite;
  315. Var i : byte;
  316. Begin
  317.   If SCNInverse then
  318.     For i:= 1 to Length( Str ) do Str[ I ] := Chr( Ord( Str[ I ] ) or 128 );
  319.   Move( Str[ 1 ] , ScnScreen[ Pred( SCNYStart + Y ) , Pred( SCNXStart + X ) ] , Length( Str ) );
  320. End;
  321.  
  322.  
  323. Procedure RNMDoWrite;
  324. Var i : byte;
  325. Begin
  326.   If SCNInverse then
  327.     For i:= 1 to Length( Str ) do Str[ I ] := Chr( Ord( Str[ I ] ) or 128 );
  328.   Move( Str[ 1 ] , ScnScreen[ Y , X ] , Length( Str ) );
  329. End;
  330.  
  331. Procedure CentreText;
  332. Var XPos : byte;
  333. Begin
  334.   If ( Y > Succ( ActYEnd - ActYStart ) ) then exit;
  335.   XPos := ( Succ( ActXEnd - ActXStart ) - Length( Str ) ) div 2;
  336.   If XPos < 0 then exit;
  337.   PutCurs( XPos , y );
  338.   DoWrite( Str );
  339. End;
  340.  
  341. Procedure SetFlash;
  342. Begin
  343.   SCNFlashing := True;
  344.   TurnOnCurs;
  345. End;
  346.  
  347. Procedure SetBlock;
  348. Begin
  349.   SCNFlashing := False;
  350.   TurnOnCurs;
  351. End;
  352.  
  353. Procedure SetSize;
  354. Begin
  355.   SCNStartLine := TopLine;
  356.   SCNEndLine := BotLine;
  357.   TurnOnCurs;
  358. End;
  359.  
  360. Function CreateWindow;
  361. Var Ptr,
  362.     Last : SCNNextWindowPtr;
  363.     Num ,
  364.     YCtr,
  365.     y,
  366.     Len : byte;
  367.     NumBytes,
  368.     Off : integer;
  369. Begin
  370.   Len := Succ( x2-x1 );
  371.   NumBytes := Len * Succ( y2-y1 );
  372.   If SCNColour then NumBytes := NumBytes * 2;
  373.   If ( MemAvail > 0 ) and ( MemAvail - NumBytes < SCNMinMemReqd ) then
  374.     Begin
  375.       CreateWindow := 0;
  376.       Exit;
  377.     End;
  378.   Num := 1;
  379.   SCNXstart := x1;
  380.   SCNYStart := Y1;
  381.   SCNXEnd   := x2;
  382.   SCNYEnd   := y2;
  383.   If SCNFirstWindow = Nil then
  384.     Begin
  385.       New( SCNFirstWindow );
  386.       Ptr := SCNFirstWindow;
  387.     End
  388.   Else
  389.     Begin
  390.       Num := Succ( Num );
  391.       Last := SCNFirstWindow;
  392.       Ptr := SCNFirstWindow^.NextWindow;
  393.       While Ptr <> Nil do
  394.         Begin
  395.           Num := Succ( Num );
  396.           Last := Ptr;
  397.           Ptr := Ptr^.NextWindow;
  398.         End;
  399.       New( Ptr );
  400.       Last^.NextWindow := Ptr;
  401.     End;
  402.   Ptr^.NextWindow := Nil;
  403.   Ptr^.XStart := x1;
  404.   Ptr^.YStart := y1;
  405.   Ptr^.XEnd   := x2;
  406.   Ptr^.YEnd   := y2;
  407.   Ptr^.XCursPos := SCNXPos;
  408.   Ptr^.YCursPos := SCNYPos;
  409.   GetMem( Ptr^.Data , NumBytes );
  410.   For y := Ptr^.YStart to Ptr^.YEnd do
  411.     Move( ScnScreen[ y , Ptr^.XStart ] , Mem[ Addr( Ptr^.Data ) + (Y - Ptr^.YStart)*Len ] , Len );
  412.   If SCNColour then
  413.    begin
  414.     SCNSetUpColRam;
  415.     Off := Succ( NumBytes div 2 );
  416.     For y := Ptr^.YStart to Ptr^.YEnd do
  417.       Move( ScnColRam[ y , Ptr^.XStart ] , Mem[ Off + Addr( Ptr^.Data ) + (Y - Ptr^.YStart)*Len ] , Len );
  418.     SCNsetUpPCGRam;
  419.    end;
  420.   ClearScreen;
  421.   If SCNBorderMode then DrawBorder;
  422.   CreateWindow := Num;
  423. End;
  424.  
  425. Function RestoreWindow;
  426. Var Ptr,
  427.     LastWindow : SCNNextWindowPtr;
  428.     Y,
  429.     Num,
  430.     Len : Byte;
  431.     off : integer;
  432. Begin
  433.   If SCNFirstWindow = Nil then
  434.     Begin
  435.       SCNInitSizes;
  436.       RestoreWindow := 0;
  437.       Exit;
  438.     End;
  439.   Num := 1;
  440.   LastWindow := SCNFirstWindow;
  441.   Ptr := SCNFirstWindow;
  442.   While Ptr^.NextWindow <> Nil do
  443.     Begin
  444.       Num := Succ( Num );
  445.       LastWindow := Ptr;
  446.       Ptr := Ptr^.NextWindow;
  447.     End;
  448.   With Ptr^ do
  449.     Begin
  450.       SCNXPos := XCursPos;
  451.       SCNYPos := YCursPos;
  452.       Len := Succ( XEnd - XStart );
  453.       For y := YStart to YEnd do
  454.         Move( Mem[ Addr( Ptr^.Data ) + (Y - YStart)*Len ] , ScnScreen[ y , XStart ] , Len );
  455.       If SCNColour then
  456.         begin
  457.           off := Succ( len * succ( YEnd - YStart ) );
  458.           SCNSetUpColRam;
  459.           For y:= YStart to YEnd do
  460.             Move( Mem[ off + Addr( Ptr^.Data ) + (Y - YStart)*Len ] , ScnColRam[ y , XStart ] , Len );
  461.           SCNSetUpPCGRam;
  462.         end;
  463.     End;
  464.   If Ptr = SCNFirstWindow then
  465.     Begin
  466.       SCNFirstWindow := Nil;
  467.       SCNInitSizes;
  468.     End
  469.   Else
  470.     Begin
  471.       With LastWindow^ do
  472.         Begin
  473.           NextWindow := Nil;
  474.           SCNXStart := XStart;
  475.           SCNYStart := YStart;
  476.           SCNXEnd   := XEnd;
  477.           SCNYEnd   := YEnd;
  478.         End;
  479.     End;
  480.   Release( Ptr );
  481.   PutCurs( SCNXPos , SCNYPos );
  482.   RestoreWindow := Num;
  483. End;
  484.  
  485. Procedure DrawBorder;
  486. Var i : byte;
  487. Begin
  488.   ScnScreen[ SCNYStart , SCNXStart ] := TL;
  489.   ScnScreen[ SCNYStart , SCNXEnd ] := TR;
  490.   ScnScreen[ SCNYEnd , SCNXStart ] := BL;
  491.   ScnScreen[ SCNYEnd , SCNXEnd ] := BR;
  492.   For i:= Succ( SCNYStart ) to Pred( SCNYEnd ) do
  493.     Begin
  494.       ScnScreen[ I , SCNXStart ] := LM;
  495.       ScnScreen[ I , SCNXEnd ] := RM;
  496.     End;
  497.   For i:= Succ( SCNXStart ) to Pred( SCNXEnd ) do
  498.     Begin
  499.       ScnScreen[ SCNYStart , i ] := TM;
  500.       ScnScreen[ SCNYEnd , i ] := BM;
  501.     End;
  502. End;