home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 24b / machinfo.zip / MACHINFO.PAS < prev   
Pascal/Delphi Source File  |  1986-04-27  |  17KB  |  697 lines

  1.  
  2. PROGRAM  MachineInformation;
  3. {
  4.   By:  Drew O. Letcher
  5.        Iowa City, IA
  6.        April, 1986
  7.  
  8.   Figures out your machine configuration including:
  9.      Machine Type
  10.      BIOS Version Date
  11.      Amount of Memory - Dip switches, tested, available to DOS
  12.      Number and Size of Disk Drives
  13.      Number and Size of Hard Drives
  14.      Adapter Boards Installed
  15.      Monitor Mode
  16.      DOS version
  17.  
  18.   These routines try to use the highest level access to the system that is
  19.   possible.  In this order:
  20.        DOS services
  21.        BIOS services
  22.        System Data Area
  23.        Chip registers
  24.  
  25. }
  26.  
  27. {  ***  set compiler directives  ***  }
  28. {$C+}  {  use of ^C and ^S during I/O  }
  29. {$U+}  {  user interrupt with ^C  }
  30. {$I+}  {  disk I/O error checking  }
  31. {$B+}  {  set con/term as standard I/O device  }
  32. { $G128} {  console input buffer  }
  33. { $P128} {  console output buffer }
  34. {$D+}  {  logical device checking for text files  }
  35. {$F16} {  number of open files  }
  36. {$R+}  {  array index range checking  }
  37. {$V+}  {  type checking of string parameters }
  38. {$K+}  {  check stack space for variables on procedure calls }
  39.  
  40.  
  41. CONST
  42.    Debug = false;
  43.  
  44. VAR
  45.    Registers : RECORD CASE integer OF
  46.                   1 : ( AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : integer );
  47.                   2 : ( AL, AH, BL, BH, CL, CH, DL, DH            : byte    );
  48.                END;
  49.  
  50.    I,
  51.    L,
  52.    NumFloppy,
  53.    NumFixed    : byte;
  54.  
  55.    EquipByte1,
  56.    EquipByte2  : byte;
  57.  
  58.    Machine     : string[ 2 ];
  59.    DOS         : byte;
  60.  
  61.  
  62. {$I CharAttr.tur }
  63. {$I Box.tur }
  64.  
  65.  
  66. PROCEDURE WriteHex( Val, Len : integer );
  67. {  write Val as a hexidecimal Number with len digits  }
  68.  
  69.    VAR
  70.       X : integer;
  71.  
  72.    BEGIN
  73.       IF Val < 0 THEN
  74.          BEGIN
  75.          Val := Val + 32767 + 1;
  76.          X := ( Val DIV 16 ) + 2048;
  77.          Val := Val MOD 16;
  78.          END
  79.       ELSE
  80.          BEGIN
  81.          X := Val DIV 16;
  82.          Val := Val MOD 16;
  83.          END;
  84.  
  85.       IF Len > 1 THEN WriteHex( X, Len-1 );
  86.  
  87.       IF Val < 10 THEN
  88.          BEGIN
  89.          Write( CHR( Val + Ord('0') ) );
  90.          END
  91.       ELSE
  92.          BEGIN
  93.          Write( CHR( ( Val - 10 ) + Ord( 'A' ) ) );
  94.          END;
  95.  
  96.    END (* Procedure WriteHex *);
  97.  
  98.  
  99. PROCEDURE  Time;
  100.  
  101.    VAR
  102.       Hour, Min, Sec  :  string[2];
  103.  
  104.    BEGIN
  105.       WITH Registers DO
  106.          BEGIN
  107.          AH := $2C;
  108.          MSDOS( Registers );
  109.          Str( CH, Hour);
  110.  
  111.          Str( CL, Min);
  112.          IF Length( Min ) < 2 THEN  Min := '0' + Min;
  113.  
  114.          Str( DH, Sec);
  115.          IF Length( Sec ) < 2 THEN
  116.             Sec := '0' + Sec;
  117.          END;
  118.  
  119.       GotoXY( 1,L ); L := L + 1;
  120.       Write( 'Time:  ':25, Hour, ':', Min, ':', Sec );
  121.  
  122.    END;  { **  Procedure Time  ** }
  123.  
  124.  
  125.  
  126. PROCEDURE Date;
  127.  
  128.    CONST
  129.       Days  :  ARRAY[ 0..6 ] OF string[5]  =
  130.                ( 'SUN', 'MON', 'TUES', 'WED', 'THURS', 'FRI', 'SAT' );
  131.    VAR
  132.       Month, Day  :  string[2];
  133.       Year        :  string[4];
  134.       DayOfWeek   :  string[5];
  135.  
  136.    BEGIN
  137.       WITH Registers DO
  138.          BEGIN
  139.          AH := $2A;
  140.          MsDos( Registers );
  141.          Str( CX - 1900, Year );
  142.  
  143.          Str( DL, Day );
  144.          IF Length( Day ) < 2 THEN  Day := '0' + Day;
  145.  
  146.          Str( DH, Month );
  147.          DayOfWeek := Days[ ( AL )  ];
  148.          END;
  149.  
  150.       GotoXy( 1,L ); L := L + 1;
  151.       Write( 'Date:  ':25, DayOfWeek, ' ', Month, '/', Day, '/', Year );
  152.  
  153.    END;  { **  Function Date  ** }
  154.  
  155.  
  156. PROCEDURE MachineType;
  157.  
  158.    VAR
  159.       MachType  :  byte;
  160.  
  161.    BEGIN
  162.       MachType := Mem[ $F000:$FFFE ];
  163.       GotoXY( 1,L ); L := L + 1;
  164.       Write( 'Machine Type:  ':25 );
  165.       Machine := '';
  166.       CASE MachType OF
  167.          $FC : Machine := 'AT';
  168.          $FD : Machine := 'jr';
  169.          $FE : Machine := 'XT';
  170.          $FF : Machine := 'PC';
  171.       ELSE
  172.          WriteHex( MachType, 2 );
  173.       END; { Case }
  174.       Write( Machine );
  175.  
  176.    END;  { Procedure MachineType }
  177.  
  178.  
  179. PROCEDURE  ROMBIOSDate;
  180.  
  181.    VAR
  182.       BIOSDate : string[ 8 ];
  183.       I : byte;
  184.  
  185.    BEGIN
  186.       BIOSDate := '';
  187.       FOR I := 5 TO 12 DO
  188.          BIOSDate := BiosDate + Chr( Mem[ $FFFF:I ] );
  189.  
  190.       GotoXY( 1,L ); L := L + 1;
  191.       Write( 'ROM BIOS Date:  ':25, BIOSDate );
  192.  
  193.    END;
  194.  
  195.  
  196. PROCEDURE DOSVersion;
  197.  
  198.    BEGIN
  199.    WITH Registers DO
  200.       BEGIN
  201.       AH := $30;
  202.       MSDOS( Registers );
  203.       DOS := AL;
  204.       GotoXY( 1,L ); L := L + 1;
  205.       Write( 'DOS Version:  ':25, AL, '.', AH );
  206.       END;
  207.  
  208.    END;  { Procedure DOSVersion }
  209.  
  210.  
  211. PROCEDURE MemorySize;
  212.  
  213.    VAR
  214.       Address   : integer;
  215.       Bank      : byte;
  216.       ActualMem : integer;
  217.       ConfMem   : integer;
  218.       DOSMem    : real;
  219.       OrigByte,
  220.       TestByte  : byte;
  221.  
  222.    BEGIN
  223.    { test memory by writing and reading a byte every 64K }
  224.    Bank := 1;
  225.    ActualMem := 64;
  226.    TestByte := $5E;
  227.  
  228.    WHILE Bank < 11 DO
  229.       BEGIN
  230.       Address := Bank * $1000;
  231.       OrigByte := Mem[ Address:0 ];
  232.       Mem[ Address:0 ] := TestByte;
  233.       IF Mem[ Address:0 ] = TestByte THEN
  234.          BEGIN
  235.          Mem[ Address:0 ] := OrigByte;
  236.          ActualMem := ActualMem + 64;
  237.          Bank := Bank + 1;
  238.          END { If }
  239.       ELSE
  240.          Bank := 99;
  241.       END; { While }
  242.  
  243.    GotoXY( 1,L ); L := L + 1;
  244.    Write( 'Actual Tested Memory:  ':25, ActualMem:4, 'k' );
  245.  
  246.    WITH Registers DO
  247.       BEGIN
  248.       { get configured system memory }
  249.       Intr( $12, Registers );
  250.       ConfMem := AX;
  251.       GotoXY( 1,L ); L := L + 1;
  252.       Write( 'Configured Memory Size:  ':25, ConfMem:4, 'k' );
  253.  
  254.       { get DOS free memory by figuring out where this program starts }
  255.       IF DOS >= 3 THEN
  256.          BEGIN
  257.          { get PSP address }
  258.          AH := $62;
  259.          MSDOS( Registers );
  260.          DOSMem := BX;
  261.          GotoXY( 1,L ); L := L + 1;
  262.          Write( 'DOS free memory:  ':25, ( ConfMem - DOSMem / 64.0 ):4:0, 'k' );
  263.          END
  264.       ELSE  { just use code segment value }
  265.          BEGIN
  266.          GotoXY( 1,L ); L := L + 1;
  267.          Write( 'DOS free memory:  ':25, ( ConfMem - CSeg / 64.0 ):4:0, 'k' );
  268.          END;
  269.  
  270.       END; { With }
  271.  
  272.    { check for ROM extensions }
  273.    Address := $C000;
  274.    WHILE Address <> $F700 DO
  275.       BEGIN
  276.       IF Mem[ Address:0 ] = $55 THEN
  277.          BEGIN
  278.          GotoXY( 1,L ); L := L + 1;
  279.          Write( 'ROM extension:  ':25 );
  280.          WriteHex( Address, 4 );
  281.          Write( 'h' );
  282.          END;
  283.       Address := Address + $100;
  284.       END;
  285.  
  286.    END; { Procedure MemorySize }
  287.  
  288.  
  289. PROCEDURE Equipment;
  290.  
  291.    BEGIN
  292.    WITH Registers DO
  293.       BEGIN
  294.       Intr( $11, Registers );
  295.       EquipByte1 := AL;
  296.       EquipByte2 := AH;
  297.       END;
  298.  
  299.    END; { Procedure Equipment }
  300.  
  301.  
  302. PROCEDURE MathUnit;
  303.  
  304.    BEGIN
  305.       { this info just comes from the system dip switches and may be
  306.         unreliable since humans set dip switches. }
  307.       GotoXY( 1,L ); L := L + 1;
  308.       Write( 'Math Coprocessor:  ':25 );
  309.       IF ( EquipByte1 AND $02 ) = $02 THEN
  310.          Write( 'installed' )
  311.       ELSE
  312.          Write( 'not installed' );
  313.  
  314.    END;  { Procedure MathUnit }
  315.  
  316.  
  317. PROCEDURE Drives;
  318.  
  319.    VAR
  320.       DiskType,
  321.       DriveType,
  322.       Drive1,
  323.       Drive2     : byte;
  324.       Path       : string [ 64 ];
  325.       TotalSpace,
  326.       FreeSpace,
  327.       TotalClusters,
  328.       FreeClusters,
  329.       SectorsPerCluster,
  330.       BytesPerSector     :  real;
  331.  
  332.    BEGIN
  333.  
  334.    { check number of floppy drives }
  335.    IF ( EquipByte1 AND $01 ) = $01 THEN
  336.       BEGIN
  337.       GotoXY( 1,L ); L := L + 1;
  338.       Write( '# of diskette drives:  ':25 );
  339.       NumFloppy := ( EquipByte1 AND $C0 ) DIV 64 + 1;
  340.       Write( NumFloppy );
  341.       END;
  342.  
  343.    { check number of fixed disk drives }
  344.    NumFixed := Mem[ $0040:$0075 ];
  345.    GotoXY( 1,L ); L := L + 1;
  346.    Write( '# of fixed disks:  ':25, NumFixed );
  347.  
  348.    WITH  Registers  DO
  349.       BEGIN
  350.  
  351.       { get AT disk info }
  352.       IF Machine = 'AT' THEN
  353.          BEGIN
  354.          { get AT floppy disk drive types }
  355.          Port[ $70 ] := $10;
  356.          DriveType := Port[ $71 ];
  357.          Drive1 := DriveType DIV 16;
  358.          Drive2 := DriveType MOD 16;
  359.          GotoXY( 1,L ); L := L + 1;
  360.          Write( 'Type of drive A:  ':25 );
  361.          CASE Drive1 OF
  362.             0 : Write( 'no drive' );
  363.             1 : Write( 'DD' );
  364.             2 : Write( 'HD' );
  365.          END; { Case }
  366.  
  367.          IF NumFloppy > 1 THEN
  368.             BEGIN
  369.             GotoXY( 1,L ); L := L + 1;
  370.             Write( 'Type of drive B:  ':25 );
  371.             CASE Drive2 OF
  372.                0 : Write( 'no drive' );
  373.                1 : Write( 'DD' );
  374.                2 : Write( 'HD' );
  375.             END; { Case }
  376.             END;
  377.  
  378.          { get AT fixed disk drive types }
  379.          Port[ $70 ] := $12;
  380.          DriveType := Port[ $71 ];
  381.          Drive1 := DriveType DIV 16;
  382.          Drive2 := DriveType MOD 16;
  383.          GotoXY( 1,L ); L := L + 1;
  384.          Write( 'Type of drive C:  ':25 );
  385.          IF Drive1 = 0 THEN
  386.              Write( 'no drive' )
  387.          ELSE
  388.             Write( Drive1 );
  389.  
  390.          IF NumFixed > 1 THEN
  391.             BEGIN
  392.             GotoXY( 1,L ); L := L + 1;
  393.             Write( 'Type of drive D:  ':25 );
  394.             IF Drive2 = 0 THEN
  395.                Write( 'no drive' )
  396.             ELSE
  397.                Write( Drive2 );
  398.             END;
  399.  
  400.          END; { If 'AT' }
  401.  
  402.       { get default drive }
  403.       AH := $19;
  404.       MSDOS( Registers );
  405.       GotoXY( 1,L ); L := L + 1;
  406.       Write( 'Default Drive:  ':25, Chr( 65 + AL ) + ':' );
  407.  
  408.       { check for logical drives }
  409.       AH := $0E;
  410.       DL := AL;             { use default drive we just got }
  411.       MSDOS( Registers );   { use function to set default drive }
  412.       GotoXY( 1,L ); L := L + 1;
  413.       Write( 'Logical Drives:  ':25, 'A:..', Chr( 64 + AL ), ':' );
  414.  
  415.       { get default directory }
  416.       AH := $47;
  417.       DL := 0;                         { default drive }
  418.       DS := Seg( Path );               { pass address of a string varible }
  419.       SI := Ofs( Path ) + 1;
  420.       MSDOS( Registers );
  421.       Path[ 0 ] := Chr( 0 );           { set string length to zero }
  422.       I := 1;                          { determine length of path string }
  423.       WHILE Path[ I ] <> Chr( 0 ) DO   { returned path ends with Chr(0) }
  424.          BEGIN
  425.          Path[ 0 ] := Chr( I );
  426.          I := I + 1;
  427.          END;
  428.       Path := '\' + Path;
  429.       GotoXY( 1,L ); L := L + 1;
  430.       Write( 'Current Directory:  ':25, Path );
  431.  
  432.       { get FAT info, current drive }
  433.       AH := $1B;
  434.       MSDOS( Registers );
  435.       DiskType := Mem[ DS:BX ];
  436.       GotoXY( 1,L ); L := L + 1;
  437.       Write( 'Disk type:  ':25 );
  438.       CASE DiskType OF
  439.          $FF : Write( 'DS DD 8-sec' );
  440.          $FE : Write( 'SS DD 8-sec' );
  441.          $FD : Write( 'DS DD 9-sec' );
  442.          $FC : Write( 'SS DD 9-sec' );
  443.          $F9 : Write( 'DS HD 15-sec' );
  444.          $F8 : Write( 'fixed disk' );
  445.          $CD : Write( 'not installed' );
  446.       END; { Case }
  447.  
  448.       GotoXY( 1,L ); L := L + 1;
  449.       Write( 'Cluster Size:  ':25, AL * CX, ' bytes' );
  450.  
  451.       { get disk space info }
  452.       AH := $36;
  453.       DL := 0;       { current drive }
  454.       MSDOS( Registers );
  455.       TotalClusters := DX;
  456.       FreeClusters := BX;
  457.       SectorsPerCluster := AX;
  458.       BytesPerSector := CX;
  459.       TotalSpace := TotalClusters * SectorsPerCluster * BytesPerSector;
  460.       FreeSpace := FreeClusters * SectorsPerCluster * BytesPerSector;
  461.       GotoXY( 1,L ); L := L + 1;
  462.       Write( 'Total Disk Space:  ':25, ( TotalSpace / 1024 ):6:0, 'k' );
  463.       GotoXY( 1,L ); L := L + 1;
  464.       Write( 'Free Disk Space:  ':25, ( FreeSpace / 1024 ):6:0, 'k' );
  465.  
  466.       END;  {  With  }
  467.  
  468.    END;  { Procedure Drives }
  469.  
  470.  
  471. PROCEDURE ComPorts;
  472.  
  473.    VAR
  474.       I : byte;
  475.  
  476.    BEGIN
  477. {   GotoXY( 1,L ); L := L + 1;
  478.    Write( 'Number of COM Ports:  ':25, ( EquipByte2 AND $0E ) DIV 2 );
  479. }
  480.    FOR I := 0 TO 3 DO
  481.       IF Mem[ $0040:I*2 ] <> 0 THEN
  482.          BEGIN
  483.          GotoXY( 1,L ); L := L + 1;
  484.          Write( 'Com':8, I+1, ' Port Address:  ' );
  485.          WriteHex( Mem[ $0040:I*2+1 ], 2 );
  486.          WriteHex( Mem[ $0040:I*2 ], 2);
  487.          Write( 'h' );
  488.  
  489.          { check com port status register }
  490.          WITH Registers DO
  491.             BEGIN
  492.             AH := 3;
  493.             DX := I;
  494.             Intr( $14, Registers );
  495.             IF Debug THEN
  496.                BEGIN
  497.                Write( ' ' );
  498.                WriteHex( AX, 4 );
  499.                END;
  500.             IF ( AL AND $B0 ) > 0 THEN
  501.                BEGIN
  502.                GotoXY( 1,L ); L := L + 1;
  503.                Write( '-  Device attached':29 );
  504.                END;
  505.             END; { With }
  506.          END
  507.       ELSE
  508.          BEGIN
  509.          { port not installed }
  510.          END;
  511.    END;  { Procedure ComPorts }
  512.  
  513.  
  514. PROCEDURE LptPorts;
  515.  
  516.    VAR
  517.       I : byte;
  518.  
  519.    BEGIN
  520. {   GotoXY( 1,L ); L := L + 1;
  521.    Write( 'Number of LPT Ports:  ':25, ( EquipByte2 AND $C0 ) DIV 64 );
  522. }
  523.    FOR I := 0 TO 3 DO
  524.       IF Mem[ $0040:I*2+8 ] <> 0 THEN
  525.          BEGIN
  526.          GotoXY( 1,L ); L := L + 1;
  527.          Write( 'LPT':8, I+1, ' Port Address:  ' );
  528.          WriteHex( Mem[ $0040:I*2+9 ], 2 );
  529.          WriteHex( Mem[ $0040:I*2+8 ], 2);
  530.          Write( 'h' );
  531.  
  532.          { check printer status register }
  533.          WITH Registers DO
  534.             BEGIN
  535.             AH := 2;
  536.             DX := I;
  537.             Intr( $17, Registers );
  538.             IF Debug THEN
  539.                BEGIN
  540.                Write( ' ' );
  541.                WriteHex( AH, 2 );
  542.                END;
  543.             IF  AH = $90 THEN
  544.                BEGIN
  545.                GotoXY( 1,L ); L := L + 1;
  546.                Write( '- Printer attached':29 );
  547.                END;
  548.             END; { With }
  549.          END
  550.       ELSE
  551.          BEGIN
  552.          { port not installed }
  553.          END;
  554.  
  555.    END; { Procedure LptPorts }
  556.  
  557.  
  558. PROCEDURE  GamePort;
  559.  
  560.    BEGIN
  561.    GotoXY( 1,L ); L := L + 1;
  562.    Write( 'Game Port:  ':25 );
  563.    IF ( EquipByte2 AND $10 ) = $10 THEN
  564.       Write( 'installed' )
  565.    ELSE
  566.       Write( 'not installed' );
  567.  
  568.    END;  { Procedure GamePort }
  569.  
  570.  
  571. PROCEDURE  Video;
  572.  
  573.    VAR
  574.       VideoMode : byte;
  575.       I         : integer;
  576.       Status    : byte;
  577.       Herc      : boolean;
  578.  
  579.    BEGIN
  580.    { get current video mode }
  581.    WITH Registers DO
  582.       BEGIN
  583.       AH := $0F;
  584.       Intr( $10, Registers );
  585.       GotoXY( 1,L ); L := L + 1;
  586.       Write( 'Current Video Mode:  ':25 );
  587.       CASE AL OF
  588.          0 : Write( 'B/W 40x25' );
  589.          1 : Write( 'Color 40x25' );
  590.          2 : Write( 'B/W 80x25' );
  591.          3 : Write( 'Color 80x25' );
  592.          7 : Write( 'Monochrome' );
  593.       END; { Case }
  594.       END; { With }
  595.  
  596.    { test for EGA card }
  597.    { this probably isn't the best way to do this test, but it works for now }
  598.    IF Mem[ $C000:$0000 ] = $55 THEN
  599.       BEGIN
  600.       IF ( Mem[ $C000:$001E ] = Ord( 'I' ) ) AND
  601.          ( Mem[ $C000:$001F ] = Ord( 'B' ) ) AND
  602.          ( Mem[ $C000:$0020 ] = Ord( 'M' ) ) THEN
  603.          BEGIN
  604.          GotoXY( 1,L ); L := L + 1;
  605.          Write( 'EGA adapter  ':25 );
  606.          END;
  607.       END;
  608.  
  609.    { Test for Hercules card - info recieved from Hercules Computer Tech. }
  610.    { With the Hercules card, bit 7 of the Display Status Port changes
  611.      on vertical retrace. }
  612.    Status := Port[ $03BA ] AND $80;
  613.    I := 0;
  614.    Herc := false;
  615.  
  616.    WHILE ( I < 3000 ) AND ( Herc = false ) DO
  617.       { wait to see if bit 7 changes }
  618.       BEGIN
  619.       I := I + 1;
  620.       Herc := Status <> ( Port[ $03BA ] AND $80 );
  621.       END;
  622.  
  623.    IF Herc THEN
  624.       BEGIN
  625.       GotoXY( 1,L ); L := L + 1;
  626.       Write( 'Hercules graphics  ':25 );
  627.       END;
  628.  
  629.    { test for Mono card }
  630.    Port[ $03B4 ] := $0F;
  631.    I := Port[ $0B5 ];
  632.    Port[ $03B5 ] := 100;
  633.    IF Port[ $03B5 ] = 100 THEN
  634.       BEGIN
  635.       GotoXY( 1,L ); L := L + 1;
  636.       Write( 'Monochrome adapter  ':25 );
  637.       Port[ $03B5 ] := I;
  638.       END;
  639.  
  640.    { test for color/graphics card }
  641.    Port[ $03D4 ] := $0F;
  642.    I := Port[ $03D5 ];
  643.    Port[ $03D5 ] := 100;
  644.    IF Port[ $03D5 ] = 100 THEN
  645.       BEGIN
  646.       GotoXY( 1,L ); L := L + 1;
  647.       Write( 'Color/Graphics adapter  ':25 );
  648.       Port[ $03D5 ] := I;
  649.       END;
  650.  
  651.    END;  { Procedure Video }
  652.  
  653.  
  654. BEGIN  { ** Main Routine ** }
  655. ClrScr;
  656.  
  657. Box( 1,1, 40,9, 'General' );
  658. L := 1;
  659. Date;
  660. Time;
  661. MachineType;
  662. ROMBIOSDate;
  663. MathUnit;
  664. DOSVersion;
  665.  
  666. Box( 41,1, 80,7, 'Memory' );
  667. L := 1;
  668. MemorySize;
  669.  
  670. Equipment;
  671.  
  672. Box( 1,10, 40,24, 'Drives' );
  673. L := 1;
  674. Drives;
  675.  
  676. Box( 41,8, 80,13, 'Video' );
  677. L := 1;
  678. Video;
  679.  
  680. Box( 41,14, 80,24, 'Peripherals' );
  681. L := 1;
  682. GamePort;
  683. ComPorts;
  684. LptPorts;
  685.  
  686. Window( 1,1, 80,25 );
  687. GotoXY( 2,24 );
  688. Write( '┤' );
  689. LowIntensity;
  690. ReverseVideo;
  691. Write( ' MachineInfo  --  (c) 1986 Information Software Assoc. ' );
  692. HighIntensity;
  693. Write( '├' );
  694.  
  695. END.
  696.  
  697.