Skip to content

Commit 9f8c238

Browse files
committed
Spec docs and sources
1 parent 9bd9b8e commit 9f8c238

File tree

5 files changed

+2324
-0
lines changed

5 files changed

+2324
-0
lines changed

Info/Code/Turbo Pascal/BINOBJU.PAS

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
Unit BINOBJu;
2+
3+
{
4+
5+
This unit allows TP programs to emit .OBJ-files containing data
6+
in the same format as the BINOBJ.EXE utility does
7+
8+
Author: Per B. Larsen ; CIS:75470,1320
9+
10+
Extensive information on the internals of .OBJ-files can be found in
11+
any Programmers Reference Manual to MS-DOS
12+
13+
The unit works, but it could need better I/O-error checking and handling.
14+
15+
Feel free to modify and use.
16+
17+
}
18+
19+
{==========================================================================}
20+
Interface
21+
{$I-}
22+
23+
Procedure BINOBJ(Var Data;DataLen:Word;FileName:String;PublicName:String);
24+
25+
{==========================================================================}
26+
Implementation
27+
28+
Procedure BINOBJ(Var Data;DataLen:Word;FileName:String;PublicName:String);
29+
Const
30+
TMOD:ARRAY[1..7] OF Byte = ($80,$04,$00,$02,$3A,$3A,$06);
31+
LNAM:ARRAY[1..11] OF Byte = ($96,$08,$00,$00,$04,$43,$4F,$44,$45,$00,$43);
32+
SEGD:ARRAY[1..10] OF Byte = ($98,$07,$00,$28,$00,$00,$02,$01,$01,$00);
33+
{ length- Chk}
34+
PUBD:ARRAY[1..5] OF Byte = ($90,$00,$00,$00,$01); {+NAME+}
35+
PUBT:ARRAY[1..3] OF Byte = ($00,$00,$00); {+CHECKSUM}
36+
LEDA:Byte=$A0; {+RECLEN(Data+4)+}
37+
LEDD:ARRAY[1..3] OF Byte = ($01,$00,$00); {+Data+CHECKSUM}
38+
MODE:ARRAY[1..5] OF Byte = ($8A,$02,$00,$00,$74);
39+
Var
40+
UD:FILE;
41+
I,REST,BLOCKS,DAOF,BYTES,RBYTES,FS:Word;
42+
BUFFER:ARRAY[1..2048] OF Byte;
43+
DATABUF:ARRAY[1..63,1..1024] OF Byte absolute Data;
44+
45+
Procedure CHECK(Var A;L:Word);
46+
Var
47+
I,C:Word;
48+
AR:ARRAY[1..2048] OF Byte absolute A;
49+
BEGIN
50+
C:=0;
51+
For I := 1 to PRED(L) do
52+
C := (C AND $FF)+AR[I];
53+
C := ($FF-(C AND $FF)+1) AND $FF;
54+
AR[L] := C;
55+
END;
56+
57+
BEGIN
58+
For I:=1 to length(PublicName) do
59+
PublicName[I] := upcase(PublicName[I]);
60+
FS:=DataLen;
61+
For I:=1 to length(FileName) do
62+
FileName[I]:=upcase(FileName[I]);
63+
IF pos('.',FileName)=0 THEN
64+
FileName:=FileName+'.OBJ';
65+
Assign(UD,FileName);
66+
ReWrite(UD,1);
67+
IF ioresult<>0 THEN
68+
BEGIN
69+
WriteLn('Cannot create .OBJ-file');
70+
Halt;
71+
END;
72+
Write('Writing ',FileName);
73+
BLockWrite(UD,TMOD,sizeof(TMOD),BYTES);
74+
BLockWrite(UD,LNAM,sizeof(LNAM),BYTES);
75+
SEGD[5]:=lo(FS);
76+
SEGD[6]:=hi(FS);
77+
CHECK(SEGD,sizeof(SEGD));
78+
BLockWrite(UD,SEGD,sizeof(SEGD),BYTES);
79+
FS:=4+length(PublicName)+sizeof(PUBT);
80+
PUBD[2]:=lo(FS);
81+
PUBD[3]:=hi(FS);
82+
Move(PUBD,BUFFER,sizeof(PUBD));
83+
Move(PublicName,BUFFER[sizeof(PUBD)+1],length(PublicName)+1);
84+
Move(PUBT,BUFFER[sizeof(PUBD)+length(PublicName)+2],3);
85+
CHECK(BUFFER,sizeof(PUBD)+length(PublicName)+5);
86+
DAOF:=0;
87+
BLockWrite(UD,BUFFER,sizeof(PUBD)+length(PublicName)+5,BYTES);
88+
BLOCKS := DataLen DIV 1024;
89+
REST := DataLen MOD 1024;
90+
IF REST<>0 THEN
91+
Inc(BLOCKS)
92+
ELSE
93+
REST:=1024;
94+
IF BLOCKS>63 THEN
95+
BEGIN
96+
WriteLn('Data buffer too large for BINOBJ');
97+
Halt;
98+
END;
99+
For I := 1 to BLOCKS do
100+
BEGIN
101+
IF I=BLOCKS THEN
102+
RBYTES:=REST
103+
ELSE
104+
RBYTES:=1024;
105+
BUFFER[1]:=LEDA;
106+
LEDD[2]:=lo(DAOF);
107+
LEDD[3]:=hi(DAOF);
108+
Move(LEDD,BUFFER[4],sizeof(LEDD));
109+
Move(DATABUF[I,1],BUFFER[7],1024);
110+
FS:=RBYTES+4;
111+
BUFFER[2]:=lo(FS);
112+
BUFFER[3]:=hi(FS);
113+
CHECK(BUFFER,RBYTES+7);
114+
BLockWrite(UD,BUFFER,RBYTES+7);
115+
Inc(DAOF,RBYTES);
116+
Write(DAOF:6,#8#8#8#8#8#8);
117+
END;
118+
WriteLn;
119+
BLockWrite(UD,MODE,sizeof(MODE),BYTES);
120+
Close(UD);
121+
END;
122+
123+
END.
124+

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
ZObj, version 1.00
2+
by David Neal Dubois
3+
4+
THE OBJECT FILE CREATED BY ZOBJ HAS A DIFFERENT PROGRAM INTERFACE THAN THAT
5+
OF BINOBJ. YOU MUST READ THE FULL DOCUMENTATION BEFORE USING IT.
6+
7+
This program is hereby donated to the public domain. Donations are
8+
accepted.
9+
10+
Normally, when distributing a program like this, I add enough comments so
11+
that someone who knows nothing about what I'm doing will be able learn all
12+
the pertinent details. I like to think that that is a major component of
13+
the value of the programs I distribute here. Unfortunately, in this case, I
14+
simply haven't had the time to invest. I am putting together this
15+
documentation in hurry. I would have liked to, for example, added comments
16+
so that someone who was entirely unfamiliar with the format of .OBJ files,
17+
would be able to understand exactly what is being done and why. There are
18+
also a few features that I would like to add.
19+
20+
If you find this program useful and would like to encourage me to add such
21+
documentation, or encourage me to add some more features, or encourage me
22+
to publish more useful programs like these in the future, I will accept
23+
donations. Please send these to:
24+
25+
David Neal Dubois
26+
Zelkop Software
27+
P.O. Box 5177
28+
Armdale, Nova Scotia
29+
Canada, B3L 4M7
30+
31+
If I actually receive enough money from anyone to pay for a diskette and a
32+
stamp, I'll be sure to send them any updates. (Please, make cheques payable
33+
to David Dubois).
34+
35+
---------------------------------------------------------------
36+
37+
ZObj is very similar to Borland's BinOBJ utility. It converts a binary data
38+
file into an object file that can be linked into your Turbo Pascal program.
39+
I call this OBJitizing data. It has a couple of advantages over BinOBJ:
40+
41+
[1] It eliminates the need for complex programming to find the address of
42+
your data in an overlaid unit.
43+
44+
[2] The program interface makes more sense, or least it does to me.
45+
46+
[3] It's much faster.
47+
48+
[4] It may produce smaller object files.
49+
50+
Running ZObj is similar to running BinOBJ. The command line syntax looks
51+
like this:
52+
53+
ZObj <binary file name> <object file name> <link identifier> [MaxLEDATA]
54+
55+
(The last parameter is optional, and will be explained later.)
56+
57+
Note that ZObj does not automatically add any default extensions to your
58+
file names. (One of those features I would have liked to time to add, and
59+
may be added if I receive any donations.)
60+
61+
For example, if you have a binary file called Screen1.DAT, and you want to
62+
make an object file called Screen1.OBJ, at the DOS prompt, type:
63+
64+
ZObj Screen1.DAT Screen1.OBJ Screen1Link
65+
66+
ZObj requires a somewhat different interface in your program than BinOBJ.
67+
BinOBJ requires you to define a procedure in your code. The problem is, it
68+
really isn't a procedure because it can't be called. I think this doesn't
69+
make sense. Then, with BinOBJ you have to find the address of your data
70+
using the @ operator on the procedure, which is still a little towards left
71+
field if you ask me. Besides, it doesn't work if the data is overlaid.
72+
73+
On the other hand, ZObj requires you to define a function in your program.
74+
This is a real for true function that you can call. All the function does
75+
is return the address of your data. This will work whether or not your data
76+
has been overlaid. Also, it uses no undocumented features (unlike the
77+
methods described in my write up in PC Magazine.) It should therefore be
78+
fully portable to old versions of Turbo Pascal as well as future versions.
79+
80+
Let's say for example, the binary data you have OBJitized is of a type
81+
called ScreenDataType. You may write:
82+
83+
type
84+
ScreenDataType = array [ 1 .. 4000 ] of byte;
85+
ScreenDataPtr = ^ ScreenDataType;
86+
87+
Then you can declare your function as follows:
88+
89+
function Screen1Link : ScreenDataPtr;
90+
external;
91+
{$L Screen1.OBJ}
92+
93+
Personally, I think makes a lot more sense whether or not your data is
94+
overlaid. When you call function Screen1Link, you get a pointer that you
95+
can dereference to find your data. If you have a procedure called
96+
DisplayScreen which takes one parameter of type ScreenData, you may write:
97+
98+
DisplayScreen ( Screen1Link ^ );
99+
100+
Remember, just because it gives you the correct address for overlaid
101+
OBJitized data, doesn't mean that it can keep your data from being shifted
102+
in and out of memory. If DisplayScreen, for example, was in another
103+
overlaid unit, your data might be swapped out before it had a chance to be
104+
displayed.
105+
106+
As ZObj works now, you must declare your function to be a FAR function. I
107+
did that because I always declare everything as FAR. (This might become an
108+
option if I receive any donations.) That means that you can either add the
109+
{$F+} compiler option to the function declaration, or choose "Force FAR
110+
calls" from the Options/Compile menu. Alternately, you can change the
111+
source code. I marked the appropriate place in the code. You have to change
112+
the RETF, which is $CB to a RETN, which is $C3.
113+
114+
I'll tell you now about that last command line option, MaxLEDATA. Normally,
115+
in an object file, an LEDATA record is limited to 1024 bytes. (If you don't
116+
know what an LEDATA record is, don't worry, it's not really very
117+
important. Please read on.) You can create one that is larger though. If
118+
you run TDump on it, or TLink, it will tell you that you are up a tree, but
119+
Turbo Pascal will still handle it just fine. The upside of all this, to
120+
those who don't know what I'm talking about, is that if you are OBJitizing
121+
a large file, say about 50K, and your LEDATA record is larger than 1024
122+
bytes, then your .OBJ file will turn out to be smaller. This is because
123+
there is several bytes overhead associated with each LEDATA record.
124+
(Incidently, BinOBJ doesn't even use the legal maximum of 1024, but a
125+
number somewhat smaller than this.)
126+
127+
With an extremely large file, say over 60K, this can make the difference
128+
between whether or not Turbo Pascal can actually link in your data. The TP
129+
linker will not work with an .OBJ file of larger than 64K bytes, regardless
130+
of how much code it would generate. If you specify MaxLEDATA to be a large
131+
number, say 65000, ZObj wastes no bytes in creating the .OBJ file, so you
132+
can in fact link in more data than BinOBJ will possibly allow.
133+
134+
On the command line, type:
135+
136+
ZObj LotsO.DAT LotsO.OBJ LotsOLink 65000
137+
138+
That's all I have time for now. If you have any questions or comments you
139+
can send them to the address above, or you can usually find me on
140+
CompuServe's BPROGA forum, User ID 71401,747. You can leave a message, or
141+
EasyPlex me. (Of course, questions accompanied with a donation will find
142+
their way to the top of my list.)
143+
144+
Oh, incidentally, one of the features I was planning on adding was the
145+
ability to create an .OBJ file suitable for a C program. Is any one is
146+
looking for such a thing?
147+
148+


0 commit comments

Comments
 (0)