which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			401 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			NASM
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			401 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			NASM
		
	
	
		
			Executable File
		
	
	
	
	
; Not copyrighted by Christian Spieler, 11 Feb 1996.
 | 
						|
;
 | 
						|
	TITLE   crc_i86.asm
 | 
						|
	NAME    crc_i86
 | 
						|
;
 | 
						|
; Optimized 8086 assembler version of the CRC32 calculation loop, intended
 | 
						|
; for real mode Info-ZIP programs (Zip 2.1, UnZip 5.2, and later versions).
 | 
						|
; Supported compilers are Microsoft C (DOS real mode) and Borland C(++)
 | 
						|
; (Turbo C). Watcom C (16bit) should also work.
 | 
						|
; This module was inspired by a similar module for the Amiga (Paul Kienitz).
 | 
						|
;
 | 
						|
; It replaces the `ulg crc32(ulg crc, ZCONST uch *buf, extent len)' function
 | 
						|
; in crc32.c.
 | 
						|
;
 | 
						|
; The code in this module should work with all kinds of C memory models
 | 
						|
; (except Borland's __HUGE__ model), as long as the following
 | 
						|
; restrictions are not violated:
 | 
						|
;
 | 
						|
; - The implementation assumes that the char buffer is confined to a
 | 
						|
;   64k segment. The pointer `s' to the buffer must be in a format that
 | 
						|
;   all bytes can be accessed by manipulating the offset part, only.
 | 
						|
;   This means:
 | 
						|
;   + no huge pointers
 | 
						|
;   + char buffer size < 64 kByte
 | 
						|
;
 | 
						|
; - Since the buffer size argument `n' is of type `size_t' (= unsigned short)
 | 
						|
;   for this routine, the char buffer size is limited to less than 64 kByte,
 | 
						|
;   anyway. So, the assumption above should be easily fulfilled.
 | 
						|
;
 | 
						|
;==============================================================================
 | 
						|
;
 | 
						|
; Do NOT assemble this source if external crc32 routine from zlib gets used.
 | 
						|
;
 | 
						|
ifndef USE_ZLIB
 | 
						|
;
 | 
						|
; Setup of amount of assemble time informational messages:
 | 
						|
;
 | 
						|
ifdef     DEBUG
 | 
						|
  VERBOSE_INFO EQU 1
 | 
						|
else
 | 
						|
  ifdef _AS_MSG_
 | 
						|
    VERBOSE_INFO EQU 1
 | 
						|
  else
 | 
						|
    VERBOSE_INFO EQU 0
 | 
						|
  endif
 | 
						|
endif
 | 
						|
;
 | 
						|
; Selection of memory model, and initialization of memory model
 | 
						|
; related macros:
 | 
						|
;
 | 
						|
ifndef __SMALL__
 | 
						|
  ifndef __COMPACT__
 | 
						|
    ifndef __MEDIUM__
 | 
						|
      ifndef __LARGE__
 | 
						|
        ifndef __HUGE__
 | 
						|
;         __SMALL__ EQU 1
 | 
						|
        endif
 | 
						|
      endif
 | 
						|
    endif
 | 
						|
  endif
 | 
						|
endif
 | 
						|
 | 
						|
ifdef __HUGE__
 | 
						|
; .MODEL Huge
 | 
						|
   @CodeSize  EQU 1
 | 
						|
   @DataSize  EQU 1
 | 
						|
   Save_DS    EQU 1
 | 
						|
   if VERBOSE_INFO
 | 
						|
    if1
 | 
						|
      %out Assembling for C, Huge memory model
 | 
						|
    endif
 | 
						|
   endif
 | 
						|
else
 | 
						|
   ifdef __LARGE__
 | 
						|
;      .MODEL Large
 | 
						|
      @CodeSize  EQU 1
 | 
						|
      @DataSize  EQU 1
 | 
						|
      if VERBOSE_INFO
 | 
						|
       if1
 | 
						|
         %out Assembling for C, Large memory model
 | 
						|
       endif
 | 
						|
      endif
 | 
						|
   else
 | 
						|
      ifdef __COMPACT__
 | 
						|
;         .MODEL Compact
 | 
						|
         @CodeSize  EQU 0
 | 
						|
         @DataSize  EQU 1
 | 
						|
         if VERBOSE_INFO
 | 
						|
          if1
 | 
						|
            %out Assembling for C, Compact memory model
 | 
						|
          endif
 | 
						|
         endif
 | 
						|
      else
 | 
						|
         ifdef __MEDIUM__
 | 
						|
;            .MODEL Medium
 | 
						|
            @CodeSize  EQU 1
 | 
						|
            @DataSize  EQU 0
 | 
						|
            if VERBOSE_INFO
 | 
						|
             if1
 | 
						|
               %out Assembling for C, Medium memory model
 | 
						|
             endif
 | 
						|
            endif
 | 
						|
         else
 | 
						|
;            .MODEL Small
 | 
						|
            @CodeSize  EQU 0
 | 
						|
            @DataSize  EQU 0
 | 
						|
            if VERBOSE_INFO
 | 
						|
             if1
 | 
						|
               %out Assembling for C, Small memory model
 | 
						|
             endif
 | 
						|
            endif
 | 
						|
         endif
 | 
						|
      endif
 | 
						|
   endif
 | 
						|
endif
 | 
						|
 | 
						|
if @CodeSize
 | 
						|
	LCOD_OFS	EQU	2
 | 
						|
else
 | 
						|
	LCOD_OFS	EQU	0
 | 
						|
endif
 | 
						|
 | 
						|
IF @DataSize
 | 
						|
	LDAT_OFS	EQU	2
 | 
						|
else
 | 
						|
	LDAT_OFS	EQU	0
 | 
						|
endif
 | 
						|
 | 
						|
ifdef Save_DS
 | 
						|
;			(di,si,ds)+(size, return address)
 | 
						|
	SAVE_REGS	EQU	6+(4+LCOD_OFS)
 | 
						|
else
 | 
						|
;			(di,si)+(size, return address)
 | 
						|
	SAVE_REGS	EQU	4+(4+LCOD_OFS)
 | 
						|
endif
 | 
						|
 | 
						|
;
 | 
						|
; Selection of the supported CPU instruction set and initialization
 | 
						|
; of CPU type related macros:
 | 
						|
;
 | 
						|
ifdef __586
 | 
						|
	Use_286_code	EQU	1
 | 
						|
	Align_Size	EQU	16	; paragraph alignment on Pentium
 | 
						|
        Alig_PARA	EQU	1	; paragraph aligned code segment
 | 
						|
else
 | 
						|
ifdef __486
 | 
						|
	Use_286_code	EQU	1
 | 
						|
	Align_Size	EQU	4	; dword alignment on 32 bit processors
 | 
						|
        Alig_PARA	EQU	1	; paragraph aligned code segment
 | 
						|
else
 | 
						|
ifdef __386
 | 
						|
	Use_286_code	EQU	1
 | 
						|
	Align_Size	EQU	4	; dword alignment on 32 bit processors
 | 
						|
        Alig_PARA	EQU	1	; paragraph aligned code segment
 | 
						|
else
 | 
						|
ifdef __286
 | 
						|
	Use_286_code	EQU	1
 | 
						|
	Align_Size	EQU	2	; word alignment on 16 bit processors
 | 
						|
        Alig_PARA	EQU	0	; word aligned code segment
 | 
						|
else
 | 
						|
ifdef __186
 | 
						|
	Use_186_code	EQU	1
 | 
						|
	Align_Size	EQU	2	; word alignment on 16 bit processors
 | 
						|
        Alig_PARA	EQU	0	; word aligned code segment
 | 
						|
else
 | 
						|
	Align_Size	EQU	2	; word alignment on 16 bit processors
 | 
						|
        Alig_PARA	EQU	0	; word aligned code segment
 | 
						|
endif	;?__186
 | 
						|
endif	;?__286
 | 
						|
endif	;?__386
 | 
						|
endif	;?__486
 | 
						|
endif	;?__586
 | 
						|
 | 
						|
ifdef Use_286_code
 | 
						|
	.286
 | 
						|
	Have_80x86	EQU	1
 | 
						|
else
 | 
						|
ifdef Use_186_code
 | 
						|
	.186
 | 
						|
	Have_80x86	EQU	1
 | 
						|
else
 | 
						|
	.8086
 | 
						|
	Have_80x86	EQU	0
 | 
						|
endif	;?Use_186_code
 | 
						|
endif	;?Use_286_code
 | 
						|
 | 
						|
;
 | 
						|
; Declare the segments used in this module:
 | 
						|
;
 | 
						|
if @CodeSize
 | 
						|
if Alig_PARA
 | 
						|
CRC32_TEXT	SEGMENT  PARA PUBLIC 'CODE'
 | 
						|
else
 | 
						|
CRC32_TEXT	SEGMENT  WORD PUBLIC 'CODE'
 | 
						|
endif
 | 
						|
CRC32_TEXT	ENDS
 | 
						|
else	;!@CodeSize
 | 
						|
if Alig_PARA
 | 
						|
_TEXT	SEGMENT  PARA PUBLIC 'CODE'
 | 
						|
else
 | 
						|
_TEXT	SEGMENT  WORD PUBLIC 'CODE'
 | 
						|
endif
 | 
						|
_TEXT	ENDS
 | 
						|
endif	;?@CodeSize
 | 
						|
_DATA	SEGMENT  WORD PUBLIC 'DATA'
 | 
						|
_DATA	ENDS
 | 
						|
_BSS	SEGMENT  WORD PUBLIC 'BSS'
 | 
						|
_BSS	ENDS
 | 
						|
DGROUP	GROUP	_BSS, _DATA
 | 
						|
if @DataSize
 | 
						|
	ASSUME  DS: nothing, SS: DGROUP
 | 
						|
else
 | 
						|
	ASSUME  DS: DGROUP, SS: DGROUP
 | 
						|
endif
 | 
						|
 | 
						|
if @CodeSize
 | 
						|
EXTRN	_get_crc_table:FAR
 | 
						|
else
 | 
						|
EXTRN	_get_crc_table:NEAR
 | 
						|
endif
 | 
						|
 | 
						|
 | 
						|
Do_CRC	MACRO
 | 
						|
	mov	bl,al
 | 
						|
if @DataSize
 | 
						|
	xor	bl,BYTE PTR es:[di]
 | 
						|
else
 | 
						|
	xor	bl,BYTE PTR [di]
 | 
						|
endif
 | 
						|
	inc	di
 | 
						|
	sub	bh,bh
 | 
						|
if Have_80x86
 | 
						|
	shl	bx,2
 | 
						|
else
 | 
						|
	shl	bx,1
 | 
						|
	shl	bx,1
 | 
						|
endif
 | 
						|
	mov	al,ah
 | 
						|
	mov	ah,dl
 | 
						|
	mov	dl,dh
 | 
						|
	sub	dh,dh
 | 
						|
	xor	ax,WORD PTR [bx][si]
 | 
						|
	xor	dx,WORD PTR [bx+2][si]
 | 
						|
	ENDM
 | 
						|
;
 | 
						|
Do_2	MACRO
 | 
						|
	Do_CRC
 | 
						|
	Do_CRC
 | 
						|
	ENDM
 | 
						|
Do_4	MACRO
 | 
						|
	Do_2
 | 
						|
	Do_2
 | 
						|
	ENDM
 | 
						|
;
 | 
						|
 | 
						|
IF @CodeSize
 | 
						|
CRC32_TEXT	SEGMENT
 | 
						|
	ASSUME	CS: CRC32_TEXT
 | 
						|
else
 | 
						|
_TEXT	SEGMENT
 | 
						|
	ASSUME	CS: _TEXT
 | 
						|
endif
 | 
						|
; Line 37
 | 
						|
 | 
						|
;
 | 
						|
;ulg crc32(ulg crc,
 | 
						|
;    ZCONST uch *buf,
 | 
						|
;    extend len)
 | 
						|
;
 | 
						|
	PUBLIC	_crc32
 | 
						|
if @CodeSize
 | 
						|
_crc32	PROC FAR
 | 
						|
else
 | 
						|
_crc32	PROC NEAR
 | 
						|
endif
 | 
						|
if Have_80x86
 | 
						|
	enter	WORD PTR 0,0
 | 
						|
else
 | 
						|
	push	bp
 | 
						|
	mov	bp,sp
 | 
						|
endif
 | 
						|
	push	di
 | 
						|
	push	si
 | 
						|
if @DataSize
 | 
						|
;	crc = 4+LCOD_OFS	DWORD (unsigned long)
 | 
						|
;	buf = 8+LCOD_OFS	DWORD PTR BYTE (uch *)
 | 
						|
;	len = 12+LCOD_OFS	WORD (unsigned int)
 | 
						|
else
 | 
						|
;	crc = 4+LCOD_OFS	DWORD (unsigned long)
 | 
						|
;	buf = 8+LCOD_OFS	WORD PTR BYTE (uch *)
 | 
						|
;	len = 10+LCOD_OFS	WORD (unsigned int)
 | 
						|
endif
 | 
						|
;
 | 
						|
if @DataSize
 | 
						|
	mov	ax,WORD PTR [bp+8+LCOD_OFS]	; buf
 | 
						|
	or	ax,WORD PTR [bp+10+LCOD_OFS]    ;     == NULL ?
 | 
						|
else
 | 
						|
	cmp	WORD PTR [bp+8+LCOD_OFS],0	; buf == NULL ?
 | 
						|
endif
 | 
						|
	jne	crc_update
 | 
						|
	sub	ax,ax				; crc = 0
 | 
						|
	cwd
 | 
						|
ifndef NO_UNROLLED_LOOPS
 | 
						|
	jmp	fine
 | 
						|
else
 | 
						|
	jmp	SHORT fine
 | 
						|
endif
 | 
						|
;
 | 
						|
crc_update:
 | 
						|
	call	_get_crc_table
 | 
						|
;  When used with compilers that conform to the Microsoft/Borland standard
 | 
						|
;  C calling convention, model-dependent handling is not needed, because
 | 
						|
;   _get_crc_table returns NEAR pointer.
 | 
						|
;  But Watcom C is different and does not allow one to assume DS pointing to
 | 
						|
;  DGROUP. So, we load DS with DGROUP, to be safe.
 | 
						|
;if @DataSize
 | 
						|
;	push	ds
 | 
						|
;	mov	ds,dx
 | 
						|
;	ASSUME	DS: nothing
 | 
						|
;endif
 | 
						|
	mov	si,ax				;crc_table
 | 
						|
if @DataSize
 | 
						|
	push	ds
 | 
						|
	mov	ax,SEG DGROUP
 | 
						|
	mov	ds,ax
 | 
						|
	ASSUME	DS: DGROUP
 | 
						|
endif
 | 
						|
;
 | 
						|
	mov	ax,WORD PTR [bp+4+LCOD_OFS]	;crc
 | 
						|
	mov	dx,WORD PTR [bp+6+LCOD_OFS]
 | 
						|
	not	ax
 | 
						|
	not	dx
 | 
						|
if @DataSize
 | 
						|
	les	di,DWORD PTR [bp+8+LCOD_OFS]	;buf
 | 
						|
	mov	cx,WORD PTR [bp+12+LCOD_OFS]	;len
 | 
						|
else
 | 
						|
	mov	di,WORD PTR [bp+8+LCOD_OFS]	;buf
 | 
						|
	mov	cx,WORD PTR [bp+10+LCOD_OFS]	;len
 | 
						|
endif
 | 
						|
;
 | 
						|
ifndef NO_UNROLLED_LOOPS
 | 
						|
if Have_80x86
 | 
						|
	shr	cx,2
 | 
						|
else
 | 
						|
	shr	cx,1
 | 
						|
	shr	cx,1
 | 
						|
endif
 | 
						|
	jcxz	No_Fours
 | 
						|
;
 | 
						|
	align	Align_Size		; align destination of branch
 | 
						|
Next_Four:
 | 
						|
	Do_4
 | 
						|
	loop	Next_Four
 | 
						|
;
 | 
						|
No_Fours:
 | 
						|
if @DataSize
 | 
						|
	mov	cx,WORD PTR [bp+12+LCOD_OFS]	;len
 | 
						|
else
 | 
						|
	mov	cx,WORD PTR [bp+10+LCOD_OFS]	;len
 | 
						|
endif
 | 
						|
	and	cx,00003H
 | 
						|
endif ; NO_UNROLLED_LOOPS
 | 
						|
	jcxz	done
 | 
						|
;
 | 
						|
        align   Align_Size              ; align destination of branch
 | 
						|
Next_Byte:
 | 
						|
	Do_CRC
 | 
						|
	loop	Next_Byte
 | 
						|
;
 | 
						|
done:
 | 
						|
if @DataSize
 | 
						|
	pop	ds
 | 
						|
;	ASSUME	DS: DGROUP
 | 
						|
	ASSUME	DS: nothing
 | 
						|
endif
 | 
						|
	not	ax
 | 
						|
	not	dx
 | 
						|
;
 | 
						|
fine:
 | 
						|
	pop	si
 | 
						|
	pop	di
 | 
						|
if Have_80x86
 | 
						|
	leave
 | 
						|
else
 | 
						|
	mov	sp,bp
 | 
						|
	pop	bp
 | 
						|
endif
 | 
						|
	ret
 | 
						|
 | 
						|
_crc32	ENDP
 | 
						|
 | 
						|
if @CodeSize
 | 
						|
CRC32_TEXT	ENDS
 | 
						|
else
 | 
						|
_TEXT	ENDS
 | 
						|
endif
 | 
						|
;
 | 
						|
endif ;!USE_ZLIB
 | 
						|
;
 | 
						|
END
 |