home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / b / bgi256-3.zip / BDH3.PAS < prev    next >
Pascal/Delphi Source File  |  1993-02-08  |  15KB  |  418 lines

  1. { BDH V3.0 - writes header portion of BGI driver }
  2. { Copyright (c) 1991,1992 Knight Software        }
  3. { 28 Dec 92 - fixed prob with trailing in copyright file}
  4. { 30 Jan 93 - fixed prob with gen V2.00 drivers (bad header)}
  5.  
  6. {$I-}
  7. USES DOS;
  8.  
  9. CONST
  10.   VERSION      : byte = 3;    {Version Number of header}
  11.   REVISION     : byte = 0;    {Revision number of header}
  12.   SUBREV       : byte = 1;    {Knight Software revision}
  13.   MIN_VERSION  : byte = 1;    {Minimum Version Number}
  14.   MIN_REVISION : byte = 0;    {Minimum Revision Number}
  15.   HEADER_SIZE  : word = 160;  {Size (in bytes) of header}
  16.   drv_num      : word = 0;    {driver number (not used)}
  17.   Null         : byte = 0;    {Null definition}
  18. CONST
  19.   HEADER_TEXT = 110;          {Max header text length (bytes)}
  20.   SubRev2 = 1;                {Knight Software SubRev for V2.01}
  21.   SubRev3 = 1;                {Knight Software SubRev for V3.01}
  22.  
  23. TYPE
  24.   ByteArray = array[0..65520] of byte;
  25.   String12  = string[12];
  26.   String3   = string[3];
  27.  
  28. VAR
  29.   Dname       : String[8];    {Dname is exactly eight char}
  30.   Tname,Mname : String;
  31.   Iname,Oname : String;
  32.   Hname,Stemp : String;
  33.   ISize,OSize : integer;
  34.   HSize       : integer;
  35.   i,Error     : integer;
  36.   Result      : word;
  37.   Ifile,Ofile : file;
  38.   Hfile       : file;
  39.   Mfile       : text;
  40.   Fptr        : ^ByteArray;
  41.   Hdata       : array [0..HEADER_TEXT] of char;
  42.   CodeSize    : word;
  43.   DataSize    : word;
  44.   DataOfs     : word;
  45.   CreateOK    : boolean;
  46.   Year,Month,Day,DoW : word;
  47.  
  48. CONST
  49.   CopyRightFile = 'COPYRITE.DAT';  {Copyright file name}
  50.   Header1 = 'BGI Device Driver';
  51.   Header2 = 'Copyright (c) 1991,1993 Knight Software';
  52.  
  53.   MonthStr : array[0..12] of string3 =
  54.     ('   ','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  55.  
  56. {----------------------------------------------------------------}
  57. {convert hex number in S to binary value in Result}
  58. {returns false if bad hex number, or none found}
  59. function GetHex(S:string; var Result:word):boolean;
  60. var i,j,k:integer;
  61. begin
  62.   GetHex := false;
  63.   j := 0;
  64.   Result := 0;
  65.   k := pos('H',S);
  66.   if k = 0 then Exit;
  67.   for i := 1 to pred(k) do
  68.   begin
  69.     if S[i] > ' ' then
  70.     begin
  71.       if ((S[i] > '9') and (S[i] < 'A')) or (S[i] < '0') or (S[i] > 'F') then Exit;
  72.       if S[i] > '9' then S[i] := char(ord(S[i])-7);
  73.       Result := (Result*16)+(ord(S[i])and $f);
  74.       inc(j);
  75.     end;
  76.   end;
  77.   if j > 0 then
  78.     GetHex := true;
  79. end;
  80.  
  81. {----------------------------------------------------------------}
  82. function fstr(I:integer):string;
  83. var S:string;
  84. begin
  85.   str(I,S);
  86.   fstr := S;
  87. end;
  88.  
  89. function fstr2(I:integer):string;
  90. var S:string;
  91. begin
  92.   str(I,S);
  93.   if length(S) < 2 then S := '0'+S;
  94.   fstr2 := S;
  95. end;
  96.  
  97. {----------------------------------------------------------------}
  98. { mainline code here }
  99. begin
  100.   writeln('BGI Driver Builder V3.04 - Feb 08 1993 - Copyright 1992,1993 Knight Software');
  101.   if ParamCount < 1 then
  102.   begin
  103.     writeln('Usage is:');
  104.     writeln('  BDH [drv_name] [input.BIN] [output.BGI] [mapfile.MAP] [version]');
  105.     writeln('    [drv_name] is the device name (i.e. EGA or CGA)');
  106.     writeln('    [input.BIN] is the DRIVER.BIN from EXE2BIN.');
  107.     writeln('    [output.BGI] is the DRIVER.BGI file name.');
  108.     writeln('    [mapfile.MAP] is the DRIVER.MAP file name.');
  109.     writeln('    [version] is the version number of the driver.');
  110.     Halt(1);
  111.   end;
  112.   {note: Map file is not actually read if building V2.00, but a filename}
  113.   {is required as a place holder if you want to specify the version number}
  114.  
  115.   {--------------------------------------------------------------}
  116.   {get device name - this is the name in () in the header file   }
  117.   fillchar(Dname,length(Dname),0);         {Clear Dname to zeros}
  118.   Dname := ParamStr(1);                    {Driver name from cmdline}
  119.   for i := 1 to length(Dname) do           {Convert name to uppercase}
  120.     Dname[i] := UpCase(Dname[i]);
  121.   Tname := Dname;
  122.  
  123.   {--------------------------------------------------------------}
  124.   {get input file name - if no input file name given, use header name}
  125.   Iname := Tname;
  126.   if ParamCount > 1 then
  127.     Iname := ParamStr(2);
  128.   if pos('.',Iname) <> 0 then
  129.     Iname := copy(Iname,1,pred(pos('.',Iname)));
  130.   Tname := Iname;
  131.   Mname := Iname;                          {map file may use input name}
  132.   Iname := Iname+'.BIN';
  133.   Assign(Ifile, Iname);
  134.   Reset(Ifile, 1);                         {Open input file}
  135.   Error := IOresult;
  136.   if Error <> 0 then                       {Did the open suceed?}
  137.   begin
  138.     writeln(Error,' ERROR: Could not open input file ',Iname);
  139.     Halt(2);                               {Leave the program}
  140.   end;
  141.   ISize := FileSize(Ifile);                {Get length of the file}
  142.   reset(Ifile, 1);                         {Reset the input file}
  143.   GetMem(Fptr, ISize);
  144.   blockread(Ifile, Fptr^, ISize, Result);  {Read source byte}
  145.   Close(Ifile);                                   {Close input file}
  146.   Error := IOresult;
  147.   if (Error <> 0) or (Result <> ISize) then
  148.   begin
  149.     Writeln(Error,' Error reading input file ',Iname);
  150.     Halt(4);
  151.   end;
  152.  
  153.   {--------------------------------------------------------------}
  154.   {get output file name - if no output file name given, use input name}
  155.   Oname := Tname;
  156.   if ParamCount > 2 then
  157.     Oname := ParamStr(3);
  158.   if pos('.',Oname) <> 0 then
  159.     Oname := copy(Oname,1,pred(pos('.',Oname)));
  160.   Tname := Oname;
  161.   Oname := Oname+'.BGI';
  162.   Assign(Ofile, Oname);
  163.   Rewrite(Ofile, 1);                       {Open output file}
  164.   Error := IOresult;
  165.   if Error <> 0 then                       {Did the open suceed?}
  166.   begin
  167.     writeln(Error,' ERROR: Could not open output file ',Oname);
  168.     Halt(3);                               {Leave the program}
  169.   end;
  170.  
  171.   {--------------------------------------------------------------}
  172.   {get map file name - if no map file name given, use input name}
  173.   if ParamCount > 3 then
  174.     Mname := ParamStr(4);
  175.   if pos('.',Mname) <> 0 then
  176.     Mname := copy(Mname,1,pred(pos('.',Mname)));
  177.   Mname := Mname+'.MAP';
  178.   {--------------------------------------------------------------}
  179.   {get the version number - if no version number given, use default}
  180.   if ParamCount > 4 then
  181.   begin
  182.     Stemp := ParamStr(5);
  183.     if Stemp[1] = '2' then
  184.     begin
  185.        VERSION := 2;
  186.        REVISION := 0;
  187.        SUBREV := SubRev2;
  188.        MIN_VERSION := 1;
  189.        MIN_REVISION := 0;
  190.     end
  191.     else if Stemp[1] = '3' then
  192.     begin
  193.        VERSION := 3;
  194.        REVISION := 0;
  195.        SUBREV := SubRev3;
  196.        MIN_VERSION := 1;
  197.        MIN_REVISION := 0;
  198.     end
  199.     else
  200.     begin
  201.       writeln('ERROR: Bad version number: ',Stemp);
  202.       Halt(5);
  203.     end;
  204.   end;
  205.  
  206.   CreateOK := false;
  207.   if Fptr^[15] <> VERSION then
  208.   begin
  209.     writeln('WARNING: The version number of the binary file (',Fptr^[15],') does not match');
  210.     writeln(' the version specified (',VERSION,'). Please double check the code for validity.');
  211.  
  212.     if (Fptr^[0] = $1E {pushds}) and (Fptr^[1] = $2E {segcs}) and  {check for V3.00}
  213.        (Fptr^[2] = $8E) and (Fptr^[3] = $1E {movds,[alias]}) then
  214.     begin
  215.        VERSION := 3;
  216.        REVISION := 0;      {declar it as a V3.00 file}
  217.        MIN_VERSION := 3;
  218.        MIN_REVISION := 0;
  219.        if (Fptr^[15] = 0) then
  220.        begin
  221.          writeln('The binary file appears to have been created from the Borland toolkit');
  222.          writeln('for the version 3.00 driver.');
  223.          SUBREV := 0;
  224.          CreateOK := true;
  225.        end
  226.        else if (Fptr^[15] = 3) then
  227.        begin
  228.          SUBREV := SubRev3;   {looks like our V3.00 binary, so assume so}
  229.          CreateOK := true;
  230.        end;
  231.        {else if what ever it is, it isn't us so don't create it}
  232.     end
  233.     else if (Fptr^[0] = $1E {pushds}) and (Fptr^[1] = $0E {pushcs}) and
  234.             (Fptr^[2] = $1F {popds}) and (Fptr^[3] = $FC {cld}) then
  235.     begin  {smells like a V2.0 binary}
  236.        VERSION := 2;
  237.        REVISION := 0;
  238.        if (Fptr^[12] = ord('C')) and (Fptr^[13] = ord('B')) and (Fptr^[15] = 0) then
  239.        begin
  240.          writeln('Binary file appears to be an original Version 2.00 binary.');
  241.          SUBREV := 0;
  242.          MIN_VERSION := 1;
  243.          MIN_REVISION := 0;
  244.          CreateOK := true;
  245.        end
  246.        else if (Fptr^[15] = 2) then  {looks like our V2.00 binary,}
  247.        begin                          {so assume so}
  248.          SUBREV := SubRev2;
  249.          MIN_VERSION := 1;
  250.          MIN_REVISION := 0;
  251.          CreateOK := true;
  252.        end;
  253.     end;         {if none of the above, assume the worst and bomb out}
  254.  
  255.     if CreateOK then
  256.     begin
  257.       write('Assuming: ');
  258.     end
  259.     else
  260.     begin
  261.       writeln('ERROR: The binary file is of an unknown type. Cannot create the driver.');
  262.       Halt(7);
  263.     end;
  264.   end;
  265.  
  266.   {--------------------------------------------------------------}
  267.   {we only need to do this if we are trying to build Version 3.00 or higher}
  268.   {Ver 2.00 doesn't use a data segment, so we don't need to look for it}
  269.  
  270.   if VERSION > 2 then {only if > V2.00}
  271.   begin
  272.     Assign(Mfile,Mname);
  273.     Reset(Mfile);                       {Open map file}
  274.     Error := IOresult;
  275.     if Error <> 0 then                       {Did the open suceed?}
  276.     begin
  277.       writeln(Error,' ERROR: Could not open map file ',Mname);
  278.       Halt(3);                               {Leave the program}
  279.     end;
  280.     repeat
  281.       readln(Mfile,Stemp);
  282.       if pos('DATA',Stemp) = 0 then Stemp := '';
  283.     until eof(Mfile) or (Stemp <> '');
  284.     if not(GetHex(Stemp,Result)) then
  285.     begin
  286.       writeln(Error,' ERROR: Bad map file format ',Mname);
  287.       Halt(3);                               {Leave the program}
  288.     end;
  289.  
  290.     DataOfs := Result;
  291.     CodeSize := DataOfs;
  292.     DataSize := Isize - DataOfs;
  293.   end;
  294.  
  295.   {--------------------------------------------------------------}
  296.   {get copyright string - if no file found, use internal msg}
  297.   Hname := CopyRightFile;
  298.   Assign(Hfile, Hname);
  299.   Reset(Hfile, 1);                         {Open header file}
  300.   Error := IOresult;
  301.   if Error <> 0 then                       {Did the open suceed?}
  302.   begin
  303.     writeln(Error,' ERROR: Could not open copyright file ',Hname);
  304.     writeln('Using internal copyright message:');
  305.     writeln(Header2);
  306.   end;
  307.   HSize := FileSize(Hfile);                {Get length of the file}
  308.   if HSize > HEADER_TEXT then              {Limit to max size}
  309.     HSize := HEADER_TEXT;
  310.   reset(Hfile, 1);                         {Reset the header file}
  311.   blockread(Hfile, Hdata, HSize, Result);  {Read source byte}
  312.   Close(Hfile);                               {Close header file}
  313.   Error := IOresult;
  314.   if (Error <> 0) or (Result <> HSize) then
  315.   begin
  316.     Writeln(Error,' Error reading header file ',Hname);
  317.     Halt(4);
  318.   end;
  319.   if HSize > 0 then
  320.   begin
  321.     i := 1;           {truncate any garbage from the end of Hdata}
  322.     while i < HSize do
  323.     begin
  324.       if Hdata[i] < #32 then HSize := i;
  325.       inc(i);
  326.     end;
  327.   end;
  328.  
  329.   {--------------------------------------------------------------}
  330.   {create text header to stick in front of the driver}
  331.   GetDate(Year,Month,Day,DoW);
  332.   if VERSION = 2 then
  333.     Stemp := 'pk'+#8+#8  {set the file mark}
  334.   else
  335.     Stemp := 'FBGD'+#8#8#8#8;
  336.  
  337.   Stemp := Stemp+Header1+' ('+Dname+') '+fstr(VERSION)+'.'+fstr(REVISION)+fstr(SUBREV)+'k  ';
  338.   Stemp := Stemp+MonthStr[Month]+' '+fstr2(Day)+' '+fstr(Year);  {add current date}
  339.   Stemp := Stemp+#13+#10;         {add cr/lf to first line}
  340.   if length(Stemp)+4+Hsize < 127 then
  341.   begin
  342.     for i := 0 to pred(HSize) do             {add in external header msg}
  343.       if not ((HData[i] = #$1A) or (HData[i] = #0)) then
  344.         Stemp := Stemp+HData[i];
  345.   end
  346.   else
  347.   begin
  348.      writeln('ERROR: Copyright file message too long. Using internal copyright message');
  349.      writeln(Header2);
  350.      Stemp := Stemp+Header2;  {tag it with internal copyright notice}
  351.   end;
  352.   Stemp := Stemp+#13#10#0#$1A;         {finish it with null, ^Z}
  353.  
  354.   {--------------------------------------------------------------}
  355.   {now we create the actual file}
  356.   writeln('Creating ',Dname,' V',VERSION,'.',REVISION,SUBREV,'k  ',
  357.            MonthStr[Month]+' '+fstr2(Day)+' '+fstr(Year),'  BGI driver.');
  358.  
  359.   blockwrite(Ofile, Stemp[1], length(Stemp)); {write heading info}
  360.  
  361.   blockwrite(Ofile, word(HEADER_SIZE), 2); {Write size of header}
  362.   blockwrite(Ofile, word(drv_num), 2);     {Write driver number}
  363.   case VERSION of
  364.     2 : begin
  365.           blockwrite(Ofile, word(ISize), 2);       {Size (in bytes) of driver}
  366.           blockwrite(Ofile, byte(VERSION), 1);     {Write the version number}
  367.           blockwrite(Ofile, byte(REVISION), 1);    {Write the revision number}
  368.           blockwrite(Ofile, byte(MIN_VERSION), 1); {Write the version number}
  369.           blockwrite(Ofile, byte(MIN_REVISION), 1);{Write the revision number}
  370.         end;
  371.     3 : begin
  372.           blockwrite(Ofile, word(CodeSize), 2);    {Size (in bytes) of code}
  373.           blockwrite(Ofile, byte(VERSION), 1);     {Write the version number}
  374.           blockwrite(Ofile, byte(REVISION), 1);    {Write the revision number}
  375.           blockwrite(Ofile, byte(MIN_VERSION), 1); {Write the version number}
  376.           blockwrite(Ofile, byte(MIN_REVISION), 1);{Write the revision number}
  377.           blockwrite(Ofile, word(DataOfs), 2);     {Offset of data segment}
  378.           blockwrite(Ofile, word(DataSize), 2);    {Size (in bytes) of data}
  379.         end;
  380.   end; {case}
  381.  
  382.   OSize := FilePos(Ofile);                 {Find loc in output file}
  383.   for i := OSize to $7F do
  384.     blockwrite(Ofile, byte(null), 1);      {Finish title area with 0s}
  385.  
  386.   blockwrite(Ofile, word(HEADER_SIZE), 2); {Write size of header}
  387.   blockwrite(Ofile, word(drv_num), 2);     {Write driver number}
  388.   case VERSION of
  389.     2 : begin
  390.           blockwrite(Ofile, word(ISize), 2);       {Size (in bytes) of driver}
  391.           blockwrite(Ofile, byte(VERSION), 1);     {Write the version number}
  392.           blockwrite(Ofile, byte(REVISION), 1);    {Write the revision number}
  393.           blockwrite(Ofile, byte(MIN_VERSION), 1); {Write the version number}
  394.           blockwrite(Ofile, byte(MIN_REVISION), 1);{Write the revision number}
  395.         end;
  396.     3 : begin
  397.           blockwrite(Ofile, word(CodeSize), 2);    {Size (in bytes) of code}
  398.           blockwrite(Ofile, byte(VERSION), 1);     {Write the version number}
  399.           blockwrite(Ofile, byte(REVISION), 1);    {Write the revision number}
  400.           blockwrite(Ofile, byte(MIN_VERSION), 1); {Write the version number}
  401.           blockwrite(Ofile, byte(MIN_REVISION), 1);{Write the revision number}
  402.           blockwrite(Ofile, word(DataOfs), 2);     {Offset of data segment}
  403.           blockwrite(Ofile, word(DataSize), 2);    {Size (in bytes) of data}
  404.         end;
  405.   end; {case}
  406.  
  407.   blockwrite(Ofile, DName, Length(Dname)+1);{Write device name to file}
  408.  
  409.   OSize := FilePos(Ofile)+1;               {How big is header so far}
  410.   for i := OSize to HEADER_SIZE do
  411.     blockwrite(Ofile, byte(Null), 1);      {Pad header with zeros}
  412.  
  413.   blockwrite(Ofile, Fptr^, ISize, Result); {Write the BIN file data}
  414.   FreeMem(Fptr, ISize);                    {Release heap memory}
  415.   Close(Ofile);                            {Close output file}
  416. end.
  417.  
  418.