aas@brolga.cc.uq.oz.au (Alex Sergejew) (08/01/90)
I have ported comic to MSDOS with ease and append context diffs and
a (m|t)asm-compatible version of memrchr. Apart from syntactical changes
memrchr has two changes worth considering for the minix 8088 version:
the cld to restore direction flags is important, and duplicating the exit
code thus avoiding an extra jump saves over 1% in compression time (!)
Two tables follow giving compression times and sizes for a variety of
MSDOS compression/archiving programs on an 8 MHz XT clone for ascii and binary
files. Comic's compression performance is impressive, particularly on text
files. The difference in speed between Turbo C 2.0 and MSC 5.1 compiled
versions is remarkable, as is the speed-up with an assembly-language version
of memrchr. It may also be encouraging to see the 3-fold speedup in lharc
between the all C version (1.0) and the standard MSDOS version (1.13c) with
assembly language routines and some algorithmic fine-tuning; I hope
comic can be improved in speed at least as much!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Table 1.
Times to compress comic.sha: a 70843 byte MSDOS text shar file of the
comic sources, listed in increasing compression file size order.
For the programs that store additional directory information within
the compressed file the `compress size' column has appended in parentheses
the actual compressed file size as well.
Program/Version time un-time compress/total size
-------------------------------------------------------------------
comic 1.0B/tcc 2.0 1285 20 21451
comic 1.0B/msc 5.1 946 18 21451
comic 1.0B/msc+masm 750 17 21451
PKzip 1.10 23 5 21730(21618)
pak 2.10 33 9 22056(22014)
lharc 1.0/msc 5.1 (*1) 134 30 23301(23269)
lharc 1.0/msc 5.1 (*2) 111 24 23301(23269)
lharc 1.13c 42 13 23303(23271)
lharc 1.13b/tcc+tasm 42 13 23303(23721)
larc 3.33 47 9 26951(26919)
compress 4.00 -b 16 (*3) 49 31 29310
compress 4.2 -b 16 (*4) 15 8 29598
PKarc 3.6 7 5 30717(30686)
PKpak 3.61 7 6 30717(30686)
dwc A5.01 8 6 30995(30934)
compress 4.00 -b 13 47 31 31194
compress 4.2 -b 13 17 9 31853
mdcd 1.0 17 11 31951(31829)
zoo 2.01 15 9 31998(31829)
arc 5.10 68 32 37847(37816)
Notes:
(*1) This is C Lharc 1.00 compiled with msc 5.1 "out of the box".
(*2) This is C Lharc 1.00 as distributed in comp.os.minix compiled
with msc 5.1 with full optimization.
(*3) This is compress 4.00 compiled with msc 5.1 "out of the box".
(*4) This is compress 4.2 as modified by Doug Graham so that the hash table
is limited to 64K and so that it runs faster under MS-DOS.
Table 2.
Times to compress comic.exe: the 28377 byte MSDOS binary executable file.
Entries are listed in the same order as Table 1.
Program/Version time un-time compress/total size
-------------------------------------------------------------------
comic 1.0B/tcc 2.0 1394 14 17613
comic 1.0B/msc 5.1 1055 13 17613
comic 1.0B/msc+masm 857 12 17613
PKzip 1.10 13 3 17454(17342)
pak 2.10 15 6 17914(17872)
lharc 1.0/msc 5.1 47 25 17395(17363)
lharc 1.0/msc 5.1 41 20 17395(17363)
lharc 1.13c 19 11 17395(17363)
lharc 1.13b/tcc+tasm 19 11 17395(17363)
larc 3.33 15 5 19669(19637)
compress 4.00 -b 16 28 16 22289
compress 4.2 -b 16 9 5 22289
PKarc 3.6 6 4 21637(21606)
PKpak 3.61 6 4 21637(21606)
dwc A5.01 5 4 21894(21833)
compress 4.00 -b 13 25 17 25483 (*1)
compress 4.2 -b 13 9 5 21590
mdcd 1.0 12 7 21706(21854)
zoo 2.01 10 5 22015(21846)
arc 5.10 36 17 23993(23962)
Notes:
(*1) I realize that this is very anomalous but I've checked it.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following are context diffs to the distributed comic ver 1.00 sources
to allow compilation under MSDOS MS C 5.1: included are a masm version
of the memrchr routine and a simple makefile.
*** f:comic_h.bak Mon Jul 16 10:49:22 1990
--- comic.h Mon Jul 16 19:36:34 1990
***************
*** 17,22 ****
--- 17,26 ----
#include <assert.h>
#include <stdio.h>
+ #ifdef MSC
+ # include <stdlib.h>
+ #endif
+
/*
** Compress constands.
*/
*** f:comic_c.bak Mon Jul 16 10:42:06 1990
--- comic.c Mon Jul 16 12:01:20 1990
***************
*** 11,17 ****
--- 11,19 ----
#ifdef DOS
# define TTY "CON" /* The console device under SM-DOS. */
+ #if 0
# define isatty(i) 1 /* Everything is a tty under MES-DOS. */
+ #endif
#else
# define TTY "/dev/tty"
#endif /* DOS */
***************
*** 56,70 ****
char *p;
#ifdef DOS
/*
! ** DOS needs special atention. Upercase letters and leading path
! ** must be removed.
*/
p = strrchr (name, '\\');
if (p != (char *) NULL)
name = p + 1; /* Kill path prefix. */
! for (p = name; *p != '\0'; p++)
if (isupper (*p))
*p = tolower (*p); /* Make name lowercase. */
#else
p = strrchr (name, '/');
if (p != (char *) NULL)
--- 58,77 ----
char *p;
#ifdef DOS
/*
! ** DOS needs special atention. Uppercase letters and leading path
! ** must be removed, along with the trailing '.exe'.
*/
p = strrchr (name, '\\');
if (p != (char *) NULL)
name = p + 1; /* Kill path prefix. */
! for (p = name; *p != '\0'; p++) {
if (isupper (*p))
*p = tolower (*p); /* Make name lowercase. */
+ if (*p == '.') {
+ *p = '\0'; /* Kill name suffix. */
+ break;
+ }
+ }
#else
p = strrchr (name, '/');
if (p != (char *) NULL)
***************
*** 167,172 ****
--- 174,182 ----
fflush (stderr);
return 0; /* Report error. */
}
+ #ifdef DOS
+ (void) setmode (0, O_BINARY); /* Set stdin to binary mode */
+ #endif /* DOS */
/*
** If the cat flag is set, don't reopen stdout.
***************
*** 200,205 ****
--- 210,218 ----
fflush (stderr);
return 0; /* Report fail. */
}
+ #ifdef DOS
+ (void) setmode (1, O_BINARY); /* Set stdout to binary mode */
+ #endif /* DOS */
return 1; /* Return success. */
}
*** f:bits.bak Mon Jul 16 10:42:04 1990
--- bits.c Mon Jul 16 11:43:32 1990
***************
*** 94,100 ****
*/
static void write_io_buff ()
{
! #ifdef DOS
(void) setmode (1, O_BINARY); /* Fails some times. ;-( */
#endif /* DOS */
if (write (1, io_buff, io_index) != io_index)
--- 94,100 ----
*/
static void write_io_buff ()
{
! #ifdef DOS_NEVER
(void) setmode (1, O_BINARY); /* Fails some times. ;-( */
#endif /* DOS */
if (write (1, io_buff, io_index) != io_index)
***************
*** 108,114 ****
*/
static void read_io_buff ()
{
! #ifdef DOS
(void) setmode (0, O_BINARY); /* Fails for me. ;-( */
#endif /* DOS */
--- 108,114 ----
*/
static void read_io_buff ()
{
! #ifdef DOS_NEVER
(void) setmode (0, O_BINARY); /* Fails for me. ;-( */
#endif /* DOS */
*** /dev/null
--- memrchr.asm Wed Aug 01 15:52:46 1990
***************
*** 0 ****
--- 1,71 ----
+ page 60, 132
+ title memrchr - reverse memory search for a char
+
+ ; Memrchr: Look for a char.
+ ; (p) Jan-Mark Wams (email: jms@cs.vu.nl)
+ ; Usage memrchr (char *start, char *stop, char c);
+ ; Return value: 0 if char is not found, a pointer to the char other wise.
+ ; Note the lib function `memchr()' uses a count, we a stop pointer.
+ ;
+ ; Modified for use with MSC 5.1 and masm: Alex A Sergejew (aas@cc.uq.oz.au)
+ ; Small Model only!
+ ; Assemble with (m|t)asm -mx memrchr...
+
+ _text segment word public 'code'
+ _text ends
+ _data segment word public 'data'
+ _data ends
+ _bss segment word public 'bss'
+ _bss ends
+ dgroup group _bss, _data
+ assume cs:_text, ds:dgroup, ss:dgroup
+
+ _text segment
+ public _memrchr ; Make it accessible for others.
+
+ _memrchr proc near
+ push bp ; C prolog
+ mov bp, sp ;
+ push si ; Get ready
+ push di ; for cdsret
+ ; push cx
+
+ mov di, 4[bp] ; Get start
+ mov si, 6[bp] ; Get stop.
+ mov al, 8[bp] ; Get c in al.
+
+ mov ah, [si] ; Save original value
+ mov [si], al ; Put sentinel in place.
+
+ std ; Count down, ie. di-- (NO: pushf, popf!)
+ mov cx, -1 ; Set counter to max.
+ repne scasb ; Loop till byte found.
+ inc di ; Hip hip... ;-(
+ cld ; Restore direction flag
+
+ FOUND:
+ mov [si], ah ; Restore original value
+ cmp di, si ; End reached?
+ je NOTFOUND ; IF so no match.
+
+ mov ax, di ; return found loc
+ ;;; jmp _cdsret ;;; skip extra jump....
+ ; pop cx
+ pop di
+ pop si
+ pop bp
+ ret
+
+ NOTFOUND:
+ xor ax, ax ; return (char *) NULL
+ _cdsret:
+ ; pop cx
+ pop di
+ pop si
+ pop bp
+ ret
+
+ _memrchr endp
+
+ _text ends
+ end
*** /dev/null
--- makefile.msc Mon Jul 16 21:29:02 1990
***************
*** 0 ****
--- 1,44 ----
+ #
+ # Makefile for comic
+ #
+ # (p) Jan-Mark Wams (email: jsm@cs.vu.nl)
+ #
+ # MSDOS MS C v5.1 version
+ #
+
+ CC=cl
+ AS=masm
+ AFLAGS=-mx
+ CFLAGS=-AS -Ox -Gs -DDOS -DMSC -nologo #-DNDEBUG
+ LFLAGS=-Gs -Fecomic.exe
+
+ OBJS=bits.obj comic.obj decode.obj encode.obj getinput.obj gettoken.obj \
+ header.obj huffman.obj
+
+ comic.exe: $(OBJS) memrchr.obj
+ $(CC) $(LFLAGS) $(OBJS) memrchr.obj
+
+ .c.obj:
+ $(CC) $(CFLAGS) -c $<
+
+
+ bits.obj: bits.h comic.h bits.c
+
+ comic.obj: buffer.h comic.h comic.c
+
+ decode.obj: bits.h buffer.h comic.h huffman.h decode.c header.h
+
+ encode.obj: bits.h buffer.h comic.h huffman.h encode.c header.h
+
+ getinput.obj: buffer.h comic.h getinput.c
+
+ gettoken.obj: buffer.h comic.h gettoken.c
+
+ huffman.obj: comic.h huffman.h tables.h huffman.c
+
+ cmemrchr.obj: comic.h
+
+ header.obj: comic.h header.h header.c
+
+ memrchr.obj: memrchr.asm
+ $(AS) $(AFLAGS) $*;jms@cs.vu.nl (Jan-Mark) (08/05/90)
In article <1990Aug1.091912.10529@brolga.cc.uq.oz.au>, aas@brolga.cc.uq.oz.au (Alex Sergejew) writes: > I have ported comic to MSDOS with ease and append context diffs and > a (m|t)asm-compatible version of memrchr. Apart from syntactical changes > memrchr has two changes worth considering for the minix 8088 version: > the cld to restore direction flags is important, and duplicating the exit > code thus avoiding an extra jump saves over 1% in compression time (!) Nice, but why didn't you email me first. The 1.0 version outdates your patches. But I would like 1.0 for MSC. I don't have MSC. ;-( SO: DON'T TRY THE PATCHES ON COMIC 1.0. AND PATCHING COMIC 1.0B WILL NOT GIVE YOU 1.0. -- (:> jms (_) ========""======