Revision | 196 (tree) |
---|---|
Time | 2020-12-23 22:58:39 |
Author | mateuszviste |
optimized memory usage (using a static buffer instead of malloc, unless it is DOS and AMB contains "big" articles)
@@ -191,12 +191,12 @@ | ||
191 | 191 | } |
192 | 192 | |
193 | 193 | |
194 | +#ifdef REALDOS | |
194 | 195 | /* allocates a 64K buffer and returns a ptr to it or NULL on failure */ |
195 | 196 | static void far *ALLOC64K(void) { |
196 | 197 | /* NOTE OpenWatcom's malloc() is unable to allocate a full 64K block due |
197 | 198 | * to OpenWatcom's book-keeping overhead, that's why a direct DOS call is |
198 | 199 | * performed instead */ |
199 | -#ifdef REALDOS | |
200 | 200 | union REGS r; |
201 | 201 | r.h.ah = 0x48; |
202 | 202 | r.x.bx = 4096; /* request 4096 paragraphs (16 bytes each, ie. 64K total) */ |
@@ -203,23 +203,8 @@ | ||
203 | 203 | int86(0x21, &r, &r); /* CF should be clear, AX = segment of allocated block */ |
204 | 204 | if (r.x.cflag != 0) return(NULL); |
205 | 205 | return(MK_FP(r.x.ax, 0)); |
206 | -#else | |
207 | - return(malloc(65536)); | |
208 | -#endif | |
209 | 206 | } |
210 | - | |
211 | - | |
212 | -static void FREE64K(void far *buffer) { | |
213 | -#ifdef REALDOS | |
214 | - union REGS r; | |
215 | - struct SREGS sr; | |
216 | - r.h.ah = 0x49; /* DOS 2+ free allocated memory segment */ | |
217 | - sr.es = FP_SEG(buffer); | |
218 | - int86x(0x21, &r, &r, &sr); | |
219 | -#else | |
220 | - free(buffer); | |
221 | 207 | #endif |
222 | -} | |
223 | 208 | |
224 | 209 | |
225 | 210 | /* returns the length of a link target (ie. content until a ':' character) */ |
@@ -895,7 +880,6 @@ | ||
895 | 880 | |
896 | 881 | int main(int argc, char **argv) { |
897 | 882 | FILEHANDLE fd = FILEHANDLE_NONE; |
898 | - char far *ama = NULL; | |
899 | 883 | char *errmsg = NULL; |
900 | 884 | unsigned short filescount; |
901 | 885 | unsigned char colscheme[AMA_HIDDEN]; |
@@ -906,6 +890,12 @@ | ||
906 | 890 | unsigned short curslot; |
907 | 891 | unsigned short index_slot; |
908 | 892 | int errflag; |
893 | +#ifdef REALDOS | |
894 | + static char staticbuff[50 * 1024u]; /* can't have full 64K in a COM file, sorry */ | |
895 | + char far *ama = staticbuff; | |
896 | +#else | |
897 | + static char ama[65536u]; | |
898 | +#endif | |
909 | 899 | |
910 | 900 | if ((argc < 2) || (argc > 3) || (argv[1][0] == '/')) { |
911 | 901 | errmsg = "usage: amb file.amb [chaptername]"; |
@@ -918,12 +908,6 @@ | ||
918 | 908 | goto EARLY_QUIT; |
919 | 909 | } |
920 | 910 | |
921 | - ama = ALLOC64K(); | |
922 | - if (ama == NULL) { | |
923 | - errmsg = "ERROR: out of memory"; | |
924 | - goto EARLY_QUIT; | |
925 | - } | |
926 | - | |
927 | 911 | if ((FREAD(ama, 4, fd) != 4) || (ama[0] != 'A') || (ama[1] != 'M') || (ama[2] != 'B') || (ama[3] != '1') || (FREAD(ama, 2, fd) != 2)) { |
928 | 912 | errmsg = "ERROR: invalid file format"; |
929 | 913 | goto EARLY_QUIT; |
@@ -938,6 +922,33 @@ | ||
938 | 922 | goto EARLY_QUIT; |
939 | 923 | } |
940 | 924 | |
925 | + /* look how big the biggest file is in the AMB archive, so I know whether | |
926 | + * or not I need to allocate a "big" memory buffer (16-bit DOS only) | |
927 | + * NOTE: I never free the allocated block, DOS does that at program's end */ | |
928 | +#ifdef REALDOS | |
929 | + { | |
930 | + unsigned short i; | |
931 | + unsigned short biggest = 0; | |
932 | + unsigned short sz; | |
933 | + for (i = filescount; i != 0; i--) { | |
934 | + if (FREAD(ama, 20, fd) != 20) { | |
935 | + } | |
936 | + sz = (unsigned char)(ama[17]); | |
937 | + sz <<= 8; | |
938 | + sz |= (unsigned char)(ama[16]); | |
939 | + if (sz > biggest) biggest = sz; | |
940 | + } | |
941 | + /* do I need a buffer bigger than my static buffer? */ | |
942 | + if (biggest >= sizeof(staticbuff)) { | |
943 | + ama = ALLOC64K(); | |
944 | + if (ama == NULL) { | |
945 | + errmsg = "ERROR: out of memory"; | |
946 | + goto EARLY_QUIT; | |
947 | + } | |
948 | + } | |
949 | + } | |
950 | +#endif | |
951 | + | |
941 | 952 | /* look for specific chapter if user asked for it */ |
942 | 953 | if (argc == 3) { |
943 | 954 | char userchap[16]; |
@@ -1055,7 +1066,6 @@ | ||
1055 | 1066 | ptui_close(); |
1056 | 1067 | } |
1057 | 1068 | if (fd != FILEHANDLE_NONE) FCLOSE(fd); |
1058 | - FREE64K(ama); | |
1059 | 1069 | if (errmsg != NULL) { |
1060 | 1070 | PUTS(errmsg); |
1061 | 1071 | return(1); |
@@ -13,7 +13,7 @@ | ||
13 | 13 | equivalent of a *.CHM help file. |
14 | 14 | AMB is a multiplatform tool, available for Linux, Windows and real mode DOS. |
15 | 15 | It is designed for minimum hardware requirements - the DOS version needs an |
16 | -IBM PC-compatible machine with DOS 2+ and some 80 KiB of available RAM. | |
16 | +IBM PC-compatible machine with DOS 2+ and 64 KiB of available RAM. | |
17 | 17 | |
18 | 18 | |
19 | 19 | === USAGE ==================================================================== |
@@ -53,6 +53,7 @@ | ||
53 | 53 | - mouse support |
54 | 54 | - optimized display routines (refresh only lines that may have changed) |
55 | 55 | - optimized next-link-lookup (tab) so it is fast even on a 4 MHz machines |
56 | + - optimized memory usage | |
56 | 57 | - reloading same page does not insert a new history position |
57 | 58 | - ported to the Windows platform (compiled with Mingw) |
58 | 59 |