home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w048 / 2.ddi / MSSRC.ARC / MSSCRN1.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-21  |  17.7 KB  |  515 lines

  1. {                              MSSCRN1.PAS
  2.                                  MS 4.0
  3.               Copyright (c) 1985, 87 by Borland International, Inc.            }
  4.  
  5. {$I msdirect.inc}
  6.  
  7. unit MsScrn1;
  8.   {-Fast screen writing routines}
  9.  
  10. interface
  11.  
  12. uses
  13.   Crt,                       {Basic video operations - standard unit}
  14.   Dos,                       {DOS interface - standard unit}
  15.   MsVars;                    {Global types and declarations}
  16.  
  17. const
  18.   DefNoRows = 25;            {Default number of rows/physical screen}
  19.   DefNoCols = 80;            {Default number of cols/physical screen}
  20.   CursorOff = $2000;         {Scan lines to make cursor invisible}
  21.  
  22. type
  23.   String255 = string[255];   {Longest Turbo string}
  24.   String255Ptr = ^String255; {Pointer to any string}
  25.   CharArray = array[0..DefNoCols] of Char; {Holds a line about to be written to screen}
  26.  
  27.   ColorType =                {Screen colors}
  28.   (TxtColor,                 {Text color}
  29.    BlockColor,               {Block color}
  30.    BordColor,                {Window status lines}
  31.    CmdColor,                 {Command line color}
  32.    CursorColor,              {Color for solid block cursor, if activated}
  33.    MnColor,                  {Normal menu color}
  34.    MfColor,                  {Menu frame color}
  35.    MsColor,                  {Selected menu item color}
  36.    MhColor,                  {Highlighted selection character in menu}
  37.    BoldColor,                {Color for bold attribute}
  38.    DblColor,                 {Color for doublestrike attribute}
  39.    UndColor,                 {Color for underscore attribute}
  40.    SupColor,                 {Color for superscript attribute}
  41.    SubColor,                 {Color for subscript attribute}
  42.    Alt1Color,                {Color for alternate 1 attribute - Compressed}
  43.    Alt2Color                 {Color for alternate 2 attribute - Italic}
  44.    );
  45.  
  46.   {Stores screen attributes}
  47.   AttributeArray = array[ColorType] of Byte;
  48.   {Stores attributes to use for combined fonts}
  49.   FontAttributeArray = array[0..255] of Byte;
  50.  
  51.   BoxType = (NormalBox, ErrorBox); {Defines types of popup prompt windows}
  52.   BoxAttribute = array[BoxType] of Byte; {Defines video attributes for different types}
  53.  
  54. var
  55.   ScreenAdr : Word;          {Base address of video memory}
  56.   PhyScrCols : Integer;      {Columns per screen row}
  57.   RetraceMode : Boolean;     {Check for snow on color cards?}
  58.   CtrlAttr : Byte;           {Attribute used to display control characters}
  59.   Tline : CharArray;         {Line of text to write to screen}
  60.   Aline : CharArray;         {Line of attributes to write to screen}
  61.   CursorType : Word;         {Scan lines for normal blinking cursor}
  62.   BigCursor : Word;          {Scan lines for "fat" cursor used in insert mode}
  63.   CenterCursor : Word;       {Scan lines for centerline cursor used in attribute mode}
  64.   PhyscrRows : Integer;      {Number of lines/physical screen}
  65.   LogscrRows : Integer;      {Number of lines/logical screen}
  66.   LogtopScr : Integer;       {Physical line number for logical line #1}
  67.   PromptRow : Integer;       {Physical line number for prompts and messages}
  68.   InitRetracemode : Boolean; {Set if wait for retrace is needed}
  69.   ScreenAttr : AttributeArray; {Currently selected attributes}
  70.   EgaPresent : Boolean;      {True if EGA card selected}
  71.   FontAttribute : FontAttributeArray; {Holds colors for font combinations}
  72.   FullScroll : Integer;      {Number of lines to BIOS scroll at next screen update}
  73.   TempScroll : Integer;      {Intermediate number of lines of BIOS scroll}
  74.   UpdateScreen : Boolean;    {True when text screen must be redrawn}
  75.   PromptLine : String255;    {Command line image}
  76.   HelpPromptLine : String255; {Holds prompt line with menu help for top of screen}
  77.   PromptCol : Integer;       {Column for next cmd printed on command line}
  78.   MaxPromptChars : Integer;  {Maximum characters for prompt messages}
  79.   MenuHelpPos : Integer;     {Screen column where menu help appears}
  80.   CurScrCol : Byte;          {Stores screen position for solid cursor}
  81.   CurScrRow : Byte;          {Stores screen position for solid cursor}
  82.   FrameAttr : BoxAttribute;  {Attributes for popup window frames}
  83.   TextAttr : BoxAttribute;   {Attributes for popup window text}
  84.  
  85. const
  86.  
  87.   {Marks start of SCREEN INSTALLATION AREA}
  88.   ScreenIDstring : string[24] = 'SCREEN INSTALLATION AREA';
  89.  
  90.   {Colors changeable within MicroStar}
  91.   MonoAttr : AttributeArray =
  92.   ($07,                      {TxtColor}
  93.    $0F,                      {BlockColor}
  94.    $70,                      {BordColor}
  95.    $07,                      {CmdColor}
  96.    $70,                      {CursorColor}
  97.    $07,                      {MnColor}
  98.    $0F,                      {MfColor}
  99.    $70,                      {MsColor}
  100.    $0F,                      {MhColor}
  101.    $0F,                      {BoldColor}
  102.    $0F,                      {DblColor}
  103.    $01,                      {UndColor}
  104.    $0F,                      {SupColor}
  105.    $0F,                      {SubColor}
  106.    $0F,                      {Alt1Color}
  107.    $0F                       {Alt2Color}
  108.    );
  109.  
  110.   ColorAttr : AttributeArray =
  111.   ($1E,                      {TxtColor}
  112.    $17,                      {BlockColor}
  113.    $38,                      {BordColor}
  114.    $0F,                      {CmdColor}
  115.    $4A,                      {CursorColor}
  116.    $70,                      {MnColor}
  117.    $78,                      {MfColor}
  118.    $1F,                      {MsColor}
  119.    $71,                      {MhColor}
  120.    $1F,                      {BoldColor}
  121.    $14,                      {DblColor}
  122.    $7F,                      {UndColor}
  123.    $15,                      {SupColor}
  124.    $16,                      {SubColor}
  125.    $1D,                      {Alt1Color}
  126.    $1A                       {Alt2Color}
  127.    );
  128.  
  129.   GoodColorCard : Boolean = False; {False to remove snow on color card}
  130.   SolidCursor : Boolean = False; {True to avoid blinking cursor}
  131.   Ega43lineMode : Boolean = False; {True to use 43 screen lines on EGA}
  132.  
  133.   {End of SCREEN INSTALLATION AREA}
  134.   LastScreenDefault : Byte = 0;
  135.  
  136. procedure EdFastWrite(St : string; Row, Col, Attr : Integer);
  137.   {-Writes St at Row,Col in Attr (video attribute) without snow}
  138.  
  139. procedure EdChangeAttribute(Number, Row, Col, Attr : Integer);
  140.   {-Changes Number video attributes to Attr starting at Row,Col}
  141.  
  142. procedure EdMoveFromScreen(var Source, Dest; Length : Integer);
  143.   {-Moves Length words from Source (video memory) to Dest without snow}
  144.  
  145. procedure EdMoveToScreen(var Source, Dest; Length : Integer);
  146.   {-Moves Length words from Source to Dest (video memory) without snow}
  147.  
  148. procedure EdWrline(Row : Integer);
  149.   {-General purpose text write - no character translation}
  150.  
  151. procedure EdWrlineCtrl(Row : Integer);
  152.   {-General purpose text write - ctrl chars translated}
  153.  
  154. procedure EdWindow(Xmin, Ymin, Xmax, Ymax : byte);
  155.   {-Set current window coordinates without compiler's range checking}
  156.  
  157. procedure EdSetCursor(ScanLines : Word);
  158.   {-Change the scan lines of the hardware cursor}
  159.  
  160. procedure EdSetEga43LineMode;
  161.   {-Switch EGA card into 43 line display}
  162.  
  163. procedure EdSetEga25lineMode;
  164.   {-Switch EGA card back into normal 25 line display}
  165.  
  166. procedure EdSetCursorOff;
  167.   {-turn off the hardware cursor when appropriate}
  168.  
  169. procedure EdEraseSolidCursor;
  170.   {-For appearance sake, erase the current solid cursor before scrolling}
  171.  
  172. procedure EdDrawSolidCursor;
  173.   {-Draw the solid cursor}
  174.  
  175. procedure EdRestoreScreenMode;
  176.   {-Clean up screen upon exit}
  177.  
  178. procedure EdBuildFontAttribute(var Fa : FontAttributeArray);
  179.   {-Set up the colors to use for combined fonts}
  180.  
  181. procedure EdGetScreenMode;
  182.   {-determine screen address and colors}
  183.  
  184.   {==========================================================================}
  185.  
  186. implementation
  187.  
  188. type
  189.   TAarray = array[0..160] of Char; {Combined line of char and attr for screen}
  190.  
  191. var
  192.   CoverAttr : Char;          {Screen attribute overwritten by block cursor}
  193.   EgaCursorControl : Byte absolute $40 : $87; {Deal with EGA BIOS bug}
  194.   BiosRows : Byte absolute $40:$84; {Number of screen rows reported by BIOS}
  195.   SaveEgaCurControl : Byte;  {Value of EgaCursorControl at startup}
  196.   InitScreenMode : Byte;     {The video mode on entry to program}
  197.   InitEgaRows : Byte; {Number of screen rows for initial EGA text mode}
  198.   IsVGA : Boolean;            {true if current display is a VGA}
  199.  
  200.   {$L MSSCRN1}
  201.  
  202.   procedure EdFastWrite(St : string; Row, Col, Attr : Integer); external;
  203.   procedure EdChangeAttribute(Number, Row, Col, Attr : Integer); external;
  204.   procedure EdMoveFromScreen(var Source, Dest; Length : Integer); external;
  205.   procedure EdMoveToScreen(var Source, Dest; Length : Integer); external;
  206.   procedure EdSetCursor(ScanLines : Word); external;
  207.   procedure EdMergeTA(var Sbuf); external;
  208.   procedure EdMergeTActrl(var Sbuf); external;
  209.  
  210.   procedure EdWindow(Xmin, Ymin, Xmax, Ymax : byte);
  211.     {-Set current window coordinates without compiler's range checking}
  212.   begin     {EdWindow}
  213.     WindMin := swap(pred(Ymin)) or pred(Xmin);
  214.     WindMax := swap(pred(Ymax)) or pred(Xmax);
  215.   end;      {EdWindow}
  216.  
  217.   procedure EdSetCursorOff;
  218.     {-turn off the hardware cursor when appropriate}
  219.  
  220.   begin                      {EdSetCursorOff}
  221.     if SolidCursor then
  222.       {Turn off the cursor}
  223.       EdSetCursor(CursorOff);
  224.   end;                       {EdSetCursorOff}
  225.  
  226.   procedure EdEraseSolidCursor;
  227.     {-For appearance sake, erase the current solid cursor before scrolling}
  228.  
  229.   begin                      {EdEraseSolidCursor}
  230.     EdChangeAttribute(1, CurScrRow, CurScrCol, Ord(CoverAttr));
  231.   end;                       {EdEraseSolidCursor}
  232.  
  233.   procedure EdDrawSolidCursor;
  234.     {-Draw the solid cursor}
  235.  
  236.   begin                      {EdEraseSolidCursor}
  237.     EdChangeAttribute(1, CurScrRow, CurScrCol, ScreenAttr[CursorColor]);
  238.   end;                       {EdEraseSolidCursor}
  239.  
  240.   procedure EdWrline(Row : Integer);
  241.     {-General purpose text write - no character translation}
  242.   var
  243.     Sbuf : TAarray;
  244.  
  245.   begin                      {EdWrline}
  246.     {Merge text and attribute lines}
  247.     EdMergeTA(Sbuf);
  248.     EdMoveToScreen(Sbuf, Mem[ScreenAdr: (PhyScrCols shl 1)*Pred(Row)], PhyScrCols);
  249.   end;                       {EdWrline}
  250.  
  251.   procedure EdWrlineCtrl(Row : Integer);
  252.     {-General purpose text write - ctrl chars translated}
  253.   var
  254.     Sbuf : TAarray;
  255.     M : Integer;
  256.  
  257.   begin                      {EdWrlineCtrl}
  258.     {Merge text and attribute lines, filtering control characters}
  259.     EdMergeTActrl(Sbuf);
  260.  
  261.     {Show block cursor}
  262.     if SolidCursor then
  263.       if (Row = CurScrRow) then begin
  264.         M := Pred(CurScrCol);
  265.         Sbuf[Succ(M shl 1)] := Chr(ScreenAttr[CursorColor]);
  266.         {Save the covered attribute for later restoration}
  267.         CoverAttr := Aline[M];
  268.         EdDrawSolidCursor;
  269.       end;
  270.  
  271.     EdMoveToScreen(Sbuf, Mem[ScreenAdr: (PhyScrCols shl 1)*Pred(Row)], PhyScrCols);
  272.  
  273.   end;                       {EdWrlineCtrl}
  274.  
  275.   procedure EdBuildFontAttribute(var Fa : FontAttributeArray);
  276.     {-Set up the colors to use for combined fonts}
  277.   var
  278.     B, Cord : Byte;
  279.  
  280.   begin                      {EdBuildFontAttribute}
  281.     {Nominal attribute is TxtColor}
  282.     FillChar(Fa, SizeOf(Fa), ScreenAttr[TxtColor]);
  283.  
  284.     for B := 1 to 255 do begin
  285.       {The lowest non-zero bit in the byte determines the color}
  286.       Cord := 0;
  287.       while (B and (1 shl Cord)) = 0 do
  288.         Inc(Cord);
  289.       if Cord <> 0 then
  290.         Fa[B] := ScreenAttr[ColorType(Ord(BoldColor)+Cord-Ord(PrtBold))];
  291.     end;
  292.   end;                       {EdBuildFontAttribute}
  293.  
  294.   procedure EdSetEga43LineMode;
  295.     {-Switch EGA card into 43 line display}
  296.   var
  297.     regs : registers;
  298.  
  299.   begin                      {EdSetEga43lineMode}
  300.     {Switch to 43/50 line mode}
  301.     with regs do begin
  302.       ax := $1112;
  303.       Bl := 0;
  304.     end;
  305.     intr($10, regs);
  306.     PhyscrRows := succ(BiosRows);
  307.     LogscrRows := Succ(PhyscrRows-LogtopScr);
  308.     {Turn off EGA cursor size emulation, works around bug in EGA BIOS}
  309.     EgaCursorControl := EgaCursorControl or 1;
  310.     {Set funny sizes for proper EGA hardware cursor}
  311.     CursorType := $0507;
  312.     BigCursor := $0307;
  313.     CenterCursor := $0107;
  314.     EdWindow(1, 1, PhyScrCols, PhyScrRows);
  315.   end;                       {EdSetEga43lineMode}
  316.  
  317.   procedure EdSetEga25lineMode;
  318.     {-Switch EGA card back into normal 25 line display}
  319.   var
  320.     regs : registers;
  321.  
  322.   begin                      {EdSetEga25lineMode}
  323.     with regs do begin
  324.       if IsVGA then
  325.         ax := $1114
  326.       else
  327.         ax := $1111;
  328.       Bl := 0;
  329.     end;
  330.     intr($10, regs);
  331.     PhyscrRows := Succ(BiosRows);
  332.     LogscrRows := Succ(PhyscrRows-LogtopScr);
  333.     {Set cursor back to normal}
  334.     EgaCursorControl := EgaCursorControl and not(1);
  335.     if initretracemode then begin
  336.       CursorType := $0607;
  337.       BigCursor := $0507;
  338.       CenterCursor := $0307;
  339.     end else begin
  340.       CursorType := $0B0C;
  341.       BigCursor := $090C;
  342.       CenterCursor := $050C;
  343.     end;
  344.     EdWindow(1, 1, PhyScrCols, PhyScrRows);
  345.   end;                       {EdSetEga25lineMode}
  346.  
  347.   procedure EdRestoreScreenMode;
  348.     {-Clean up screen upon exit}
  349.   var
  350.     regs : registers;
  351.  
  352.   begin                      {EdRestoreScreenMode}
  353.     {Restore the screen mode - also clears the screen}
  354.     with regs do begin
  355.       Ah := 0;
  356.       Al := InitScreenMode;
  357.       intr($10, regs);
  358.     end;
  359.  
  360.     {Get into proper line count if Ega or Vga is present}
  361.     if EgaPresent then
  362.       if InitEgaRows > 40 then
  363.         EdSetEga43LineMode
  364.       else
  365.         EdSetEga25LineMode;
  366.  
  367.  
  368.     {Restore the cursor to original scan lines}
  369.     EgaCursorControl := SaveEgaCurControl;
  370.     EdSetCursor(CursorType);
  371.   end;                       {EdRestoreScreenMode}
  372.  
  373.   function EdEgaPresent : Boolean;
  374.     {-Return True if an EGA or VGA card is installed and selected}
  375.   var
  376.     regs : registers;
  377.  
  378.   begin                    {EdEgaPresent}
  379.     with regs do begin
  380.       AX := $1C00;
  381.       CX := 7;
  382.       intr($10, regs);
  383.       if AL = $1C then begin
  384.         {VGA installed - treat it like EGA}
  385.         EdEgaPresent := True;
  386.         IsVGA := True;
  387.         exit;
  388.       end else
  389.         IsVGA := False;
  390.       AX := $1200;
  391.       BL := $32;
  392.       intr($10, regs);
  393.       if AL = $12 then begin
  394.         {MCGA installed - we don't support its 50 line mode}
  395.         EdEgaPresent := False;
  396.         GoodColorCard := True;
  397.         exit;
  398.       end;
  399.       Ah := $12;
  400.       Bl := $10;
  401.       Cx := $FFFF;
  402.       intr($10, regs);
  403.       {EGA present if CX was changed}
  404.       EdEgaPresent := (Cx <> $FFFF);
  405.     end;
  406.   end;                     {EdEgaPresent}
  407.  
  408.   procedure EdGetScreenMode;
  409.     {-Determine screen address and colors}
  410.   var
  411.     regs : registers;
  412.  
  413.   begin                      {EdGetScreenMode}
  414.  
  415.     PhyScrCols := DefNoCols; {Number of columns on the screen}
  416.     PromptRow := 1;          {Command Line is line 1 of screen}
  417.     LogtopScr := 2;          {Text windows don't use line 1 of screen}
  418.  
  419.     with regs do begin
  420.       {Get screen type}
  421.       ax := $0F00;
  422.       intr($10, regs);
  423.       InitScreenMode := Al;
  424.       SaveEgaCurControl := EgaCursorControl;
  425.       InitRetracemode := (InitScreenMode <> 7);
  426.  
  427.       {Is an EGA or VGA installed?}
  428.       EgaPresent := EdEgaPresent;
  429.  
  430.       if EgaPresent then begin
  431.         {See if in 43 line mode already}
  432.         InitEgaRows := BiosRows;
  433.         Ega43lineMode := Ega43lineMode or (InitEgaRows > 40);
  434.       end;
  435.  
  436.       {Set screen mode to appropriate 80 column mode}
  437.       Ah := 0;
  438.       case InitScreenMode of
  439.         0 : Al := 2;       {Switch from BW40 to BW80}
  440.         1 : Al := 3;       {Switch from CO40 to CO80}
  441.       else
  442.         Al := InitScreenMode; {Assure color burst correct}
  443.       end;
  444.       intr($10, regs);
  445.  
  446.       {Store number of screen rows}
  447.       PhyscrRows := DefNoRows;
  448.       LogscrRows := Succ(PhyscrRows-LogtopScr);
  449.     end;
  450.  
  451.     if EgaPresent then begin
  452.       GoodColorCard := True;
  453.       if Ega43lineMode then
  454.         {Switch to 43/50 line mode}
  455.         EdSetEga43LineMode
  456.       else
  457.         {Assure in 25/28 line mode}
  458.         EdSetEga25LineMode;
  459.     end;
  460.  
  461.     if InitRetracemode then begin
  462.       {Color card}
  463.       ScreenAdr := $B800;
  464.       case InitScreenMode of
  465.         {Color burst disabled}
  466.         0, 2 : ScreenAttr := MonoAttr;
  467.       else
  468.         {Color burst on}
  469.         ScreenAttr := ColorAttr;
  470.       end;
  471.       if not(EgaPresent and Ega43lineMode) then begin
  472.         CursorType := $0607;
  473.         BigCursor := $0507;
  474.         CenterCursor := $0307;
  475.       end;
  476.     end else begin
  477.       ScreenAdr := $B000;
  478.       ScreenAttr := MonoAttr;
  479.       if not(Ega43lineMode) then begin
  480.         CursorType := $0B0C;
  481.         BigCursor := $090C;
  482.         CenterCursor := $050C;
  483.       end;
  484.     end;
  485.  
  486.     {Set up attribute table for combined fonts}
  487.     EdBuildFontAttribute(FontAttribute);
  488.  
  489.     {Attribute used to mark control characters}
  490.     CtrlAttr := ScreenAttr[BlockColor];
  491.  
  492.     {Attributes used to draw boxes}
  493.     TextAttr[NormalBox] := ScreenAttr[MnColor];
  494.     TextAttr[ErrorBox] := ScreenAttr[CursorColor];
  495.     FrameAttr[NormalBox] := ScreenAttr[MfColor];
  496.     FrameAttr[ErrorBox] := ScreenAttr[CursorColor];
  497.  
  498.     {Don't slow down for good color cards}
  499.     RetraceMode := InitRetracemode and not(GoodColorCard);
  500.  
  501.     {Turn off cursor if appropriate}
  502.     EdSetCursorOff;
  503.   end;                       {EdGetScreenMode}
  504.  
  505. begin
  506.   EdGetScreenMode;
  507.   CoverAttr := Null;         {Attribute the block cursor covers}
  508.   UpdateScreen := True;      {Screen needs updating}
  509.   UpdateCursor := True;      {Cursor needs updating}
  510.   FullScroll := 0;           {BIOS scrolling not currently needed}
  511.   PromptCol := 1;            {Next cursor position on command line}
  512.   CurScrRow := Succ(PhyscrRows); {Put block cursor off the screen}
  513.   CurScrCol := 1;            {Initialize block cursor column}
  514. end.
  515.