Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

Freepascal and binary files? (Developers)

posted by Laaca Homepage, Czech republic, 21.05.2020, 10:36

Sure, I wrote similar converter few years ago. It is OK for small data sizes. But for bigger data sizes it is not ideal because it slowes down the compilation.


In Turbopascal is it possible with the help of utility BINOBJ.
See bellow the explanation how to do it in TP.


3. The BINOBJ Utility
=======================

A utility program called BINOBJ.EXE has been added to convert any
file to an .OBJ file so it can be linked into a pascal program as
a "procedure." This is useful if you have a binary data file that
must reside in the code segment or is too large to make into a
typed constant array. For example, you can use BINOBJ with the
Graph unit to link the graphics driver or font files directly
into your .EXE file. Then, to use your graph program, you need
only have the .EXE file (see the example BGILINK.PAS).

BINOBJ takes three parameters:

   BINOBJ  <source[.BIN]>  <destination[.OBJ]>  <public name>

where source is the binary file to convert, destination is the
name of the .OBJ to be produced, and public name is the name of
the procedure as it will be declared in your pascal program.

The following example, the procedure ShowScreen, takes a pointer
as a parameter and moves 4000 bytes of data to screen memory. The
file called MENU.DTA contains the image of the main menu screen
(80 * 25 * 2 = 4000 bytes).

Here's a simple (no error-checking) version of MYPROG.PAS:

   program MyProg;

   uses Crt;

   procedure ShowScreen(ScreenData : Pointer);
   { Display a screenful of data--no error-checking! }
   var
     ScreenSegment: Word;

   begin
     if (Lo(LastMode) = 7) then      { Mono? }
       ScreenSegment := $B000
     else
       ScreenSegment := $B800;
     Move(ScreenData^,               { From pointer }
      Ptr(ScreenSegment, 0)^,        { To video memory }
      4000);                         { 80 * 25 * 2 }
   end;

   var
     MenuP : Pointer;
     MenuF : file;
   begin
     Assign(MenuF, 'MENU.DTA');      { Open screen data file }
     Reset(MenuF, 1);
     GetMem(MenuP, 4000);            { Allocate buffer on heap }
     BlockRead(MenuF, MenuP^, 4000); { Read screen data }
     Close(MenuF);
     ShowScreen(MenuP);              { Display screen }
   end.


The screen data file (MENU.DTA) is opened and then read into a
buffer on the heap. Both MYPROG.EXE and MENU.DTA must be present
at run-time for this program to work. You can use BINOBJ to
convert MENU.DTA to an .OBJ file (MENUDTA.OBJ) and tell it to
associate the data with a procedure called MenuData. Then you can
declare the fake external procedure MenuData, which actually
contains the screen data. Once you link in the .OBJ file with the
$L compiler directive, MenuData will be 4000 bytes long and
contain your screen data. First, run BINOBJ on MENU.DTA:

   binobj MENU.DTA MENUDTA MenuData

The first parameter, MENU.DTA, shows a familiar file of screen
data; the second, MENUDTA, is the name of the .OBJ file to be
created (since you didn't specify an extension, .OBJ will be
added). The last parameter, MenuData, is the name of the external
procedure as it will be declared in your program. Now that you've
converted MENU.DTA to an .OBJ file, here's what the new
MYPROG.PAS looks like:

   program MyProg;

   uses Crt;

   procedure ShowScreen(ScreenData : Pointer);
   { Display a screenful of data--no error checking! }
   var
     ScreenSegment: Word;
   begin
     if (Lo(LastMode) = 7) then             { Mono? }
       ScreenSegment := $B000
     else
       ScreenSegment := $B800;
     Move(ScreenData^,                      { From pointer }
      Ptr(ScreenSegment, 0)^,               { To video memory }
      4000);                                { 80 * 25 * 2 }
   end;

   procedure MenuData; external;
   {$L MENUDTA.OBJ }
   begin
     ShowScreen(@MenuData);                 { Display screen }
   end.

Notice that ShowScreen didn't change at all, and that the ADDRESS
of your procedure is passed using the @ operator.

---
DOS-u-akbar!

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 251 users online (0 registered, 251 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum