1 nspark 1.7.6 dos-beta
\r
2 =====================
\r
4 The DOS port of nspark.
\r
6 Read the README file in the nspark directory first.
\r
9 DOS 2.0 or higher, 3.31 or higher recommended
\r
10 450k of free memory.
\r
12 Changes with respect to the other versions:
\r
13 The DOS version of nspark recognizes / as a command switch
\r
14 as well as the unix/RISC OS -. (In fact -x/v is a valid
\r
15 sequence of switches, as is /x -v though /x-v is not.)
\r
17 Filenames for extraction are made case insensitive, but there
\r
18 is no conversion to the DOS 8.3 characters convention. I.e.
\r
19 nspark -x archive.spk SomeFiles/Text
\r
21 nspark /x archive.spk somefiles/text
\r
23 nspark /x archive.spk somefile/text
\r
24 (though files would end up in the same directory `somefile').
\r
26 Contents of this directory:
\r
28 nspark.exe : the DOS executable
\r
29 makefile : generic makefile, derived from the general
\r
30 makefile with provisions for use of PKLITE or
\r
31 LZEXE to compress the generated executable.
\r
32 makefile.bor : makefile for Borland C/C++ derived from nspark.prj
\r
33 (Preferably use this version in stead of makefile
\r
34 and optionally apply PKLITE or LZEXE by hand.)
\r
35 nspark.prj : Borland 3.1 project file
\r
36 nspark.ide : Borland 4 project file
\r
37 alt/compress.c : alternative version of compress.c (see below)
\r
38 alt/haspragm.c : test whether #pragma startup is supported
\r
39 (called by makefile).
\r
40 alt/makefile.bor: makefile for alternative version
\r
41 alt/nspark.prj : Borland 3.1 project file for alternative version
\r
42 alt/nspark.ide : Borland 4 project file for alternative version
\r
44 Compilation/porting:
\r
45 The current version has been compiled with Borland C/C++
\r
46 versions 1, 3.1 and 4.02. I do not have access to a
\r
47 Microsoft C/C++ compiler, so I cannot test whether it will
\r
48 compile with that compiler too. Some changes will probably
\r
51 All changes for DOS are enclosed by the preprocessor macro
\r
52 __MSDOS__ (predefined by the Borland preprocessor). This
\r
53 makes things more transparent than when it was enclosed by
\r
54 #if defined(__BORLANDC__) || defined(__TURBOC__)/#endif pairs.
\r
55 So compile with -D__MSDOS__ if your compiler does not predefine
\r
57 These changes only apply for 16 bits compilers. See below
\r
58 for 32 bits/protected mode compilers. (Hardly any changes
\r
59 are necessary in that case.)
\r
61 Note that the paths in the makefiles are likely to be wrong
\r
62 for other computers than my own. So change those before
\r
63 compiling. Or change the configuration files into response files
\r
64 and use separate turboc.cfg and tlink.cfg files. (The disadvantage
\r
65 of the latter is that there may be more options specified in the
\r
66 .cfg files that are not needed/unwanted for nspark.)
\r
68 Things to look for when compiling:
\r
69 Names of header files:
\r
70 io.h is a header file under Borland C/C++. And it is needed
\r
71 for this application because it contains the read() function.
\r
72 The original nspark also had a header file io.h. This would
\r
73 not be a problem (#include "io.h" and #include <io.h> can
\r
74 happily coexist) but for the fact that both headers define
\r
75 the macro __IO_H to indicate that they have been `seen'.
\r
76 So I changed the name to nsparkio.h.
\r
77 The same problem may occur for os.h with other compilers.
\r
80 The supplied version is compiled under the compact memory
\r
81 model. It is recommended to use either the compact or the
\r
82 large memory model, because of the amount of dynamic data.
\r
83 (There is not so much code, therefore the compact model
\r
85 Because farcalloc() is used to allocate the large arrays for
\r
86 the tables needed in uncompress(), the program could be
\r
87 compiled using the small and medium memory model, but this
\r
88 restricts the space for filenames and pathnames.
\r
89 Though the manual states that farcalloc() cannot not be
\r
90 used with the tiny memory model, it IS possible to compile
\r
91 the program in .COM format. And though it saves a few kbytes
\r
92 on the size of the executable, it restricts the available
\r
93 space for dynamic data even more.
\r
96 DOS integers are 16 bit! That means that
\r
97 32768 == 65536 == (1 << 16) == 0. The result of a constant
\r
98 being considered 0 can be hard to spot. So use long or
\r
99 unsigned long constants when appropriate:
\r
100 32768L != 0 != 65536UL etc.
\r
102 ...printf() and ...scanf() format specifiers should also be
\r
103 long when appropriate.
\r
104 long l; /* ... */ printf("%d",l);
\r
105 will only print the value of the lower two bytes of l and
\r
106 the other two will appear in the next %d. I.e.:
\r
107 long l,m; /* ... */ printf("%d %d\n",l,m);
\r
109 printf("%d %d\n", (int) l, *(int*) ((char *)&l + 2) );
\r
110 produce the same output. (m is never used.) Use %ld or %lu.
\r
111 Again, the effect in e.g. a ...scanf() can be very hard to spot.
\r
113 Characters are passed to functions as integers. This produced
\r
114 quite a lot of warnings (`conversion may loose significant
\r
115 digits') in the uncompress() routines where code_ints (longs) are
\r
116 used to represent character data. A cast solves this, but these
\r
117 warnings may point to bigger problems.
\r
119 Segmented pointers and pointer arithmetic:
\r
120 DOS pointers consist of two parts: a segment and an offset.
\r
121 (The absolute address is obtained by segment * 16 + offset.)
\r
122 Both parts are 16 bit quantities.
\r
123 Under `normal' operations, pointer arithmetic is restricted
\r
124 to the offset part. This means that a pointer (or an array
\r
125 for that matter) can only accommodate 64k of memory. I.e.:
\r
126 double * dp ; /* ... */ dp == &dp[8192];
\r
127 and &dp[1] == &dp[8193]; etc. (Large numbers? uncompress()
\r
128 uses unsigned long htab[65536L]; or 256k of memory for one
\r
130 This can be overcome by using normalized or `huge' pointers.
\r
131 With these pointers, the segment part gets updated every time
\r
132 the offset becomes greater than 16 (or less than 0). The
\r
133 drawback obviously is some loss in speed.
\r
134 Also, when comparing or subtracting two pointers, both should
\r
135 either come from the same array or be normalized, otherwise
\r
136 the results of pointer arithmetic are undefined.
\r
139 Under the Borland compiler, static arrays are REALLY static.
\r
140 That is, they are part of the executable. The function
\r
141 uncompress() in nspark uses two large static arrays for the
\r
142 uncompression process. Were these static (as in the unix
\r
143 versions), the executable would contain 384k of `empty space'.
\r
144 So I changed that to dynamically allocated arrays.
\r
145 If you DO want these static arrays, compile with the macro
\r
146 BB_HUGE_STATIC_ARRAYS defined. (See compress.c). Compression
\r
147 afterwards with e.g. PKLITE or LZEXE is highly recommended in
\r
150 To correspond more to the unix way of dynamically allocating
\r
151 static arrays, there is an alternative form of compress.c
\r
152 in the directory alt. In that version the memory is allocated
\r
153 by a function that is called before main() itself by using
\r
154 #pragma startup. I do not expect that all compilers support
\r
155 this pragma, so I added it as an alternative. The program
\r
156 haspragm.c is compiled and called in the accompanying makefile
\r
157 to verify that this pragma really is present.
\r
158 The advantage of this approach is that a lack of memory is
\r
159 spotted before anything else happens. Otherwise the program
\r
160 may already have produced some output before it spots
\r
161 the lack of memory. This can be confusing for the user.
\r
163 The executable supplied is compiled with this alternative
\r
166 32 bits & protected mode.
\r
167 The present version is a 16 bit version. It should run on
\r
168 all DOS machines with sufficient memory.
\r
170 When compiling a protected mode version with a 32 bits compiler
\r
171 (like djgpp, the DOS port of the gnu compiler), hardly any
\r
172 porting is needed. But you end up with a version that will
\r
173 only run on 386 systems or better.
\r
175 Bugs/problems/improvements:
\r
177 None that I know of at the moment.
\r
180 DOS does not allow easy time/date stamping of directories.
\r
181 (To do so would mean editing the directory `file' itself,
\r
182 i.e. emulating the action of a disc editor.) Since no
\r
183 other archivers I know of do time/date stamp newly created
\r
184 directories and utilities like Norton FD or DR-DOS's TOUCH
\r
185 cannot do so either, I did not bother to implement this.
\r
186 ``It is left as an exercise for the interested reader.''
\r
187 NB: If you DO want to implement this, do not forget to
\r
188 stamp the . entry inside the directory itself and the ..
\r
189 entry in any subdirectories as well! Unlike unix, these
\r
190 are no (pseudo) links but separate entries.
\r
193 Use of XMS/EMS for the code tables used by uncompress(). This
\r
194 would allow the program to run when there is less conventional
\r
195 memory present. But I think it is more useful to compile a 32
\r
196 bits protected mode version right away. (You do not need the
\r
197 changes made to accommodate 16 bits `oddities' in that case.)
\r
200 bob@wop.wtb.tue.nl or B.A.Brand@wtb.tue.nl
\r
201 (addresses valid until at least Oct. 1st, 1996)
\r