; ::[[ @(#) addbfcrc.asm 1.1 89/07/08 10:48:28 ]]::
; assembly implementation of addbfcrc() for Turbo C 2.0 -- small memory model

; The following code was obtained from compiling addbfcrc.c using
; Turbo C 2.0, then hand-optimized.  In the interest of making
; faster CRC-32 calculations available to all, I hereby release
; the contents of this file to the public domain.  This code is for
; the small memory model only.  It will probably need to be revised
; for use with other C compilers.
;                                    -- Rahul Dhesi 1989/07/08

_DATA   segment word public 'DATA'
_DATA   ends

        extrn   _crccode:word
        extrn   _crctab:word
        public  _addbfcrc

_TEXT   segment byte public 'CODE'

DGROUP  group   _DATA
        assume  cs:_TEXT,ds:DGROUP,ss:DGROUP

;void addbfcrc (buf, size) char *buf, int size

_addbfcrc       proc    near
        push    bp
        mov     bp,sp
        sub     sp,2
        push    si
        push    di
        mov     cx,word ptr [bp+6]      ;cx = size
        mov     si,word ptr [bp+4]      ;si = buf

        xor     di,di                   ;i = 0

        jcxz    done                    ;if size = 0, nothing to do
@loop:

;      crccode = crctab[(int) ((crccode) ^ (buf[i])) & 0xff] ^
;         (((crccode) >> 8) & 0x00FFFFFFL);

;       (dx,ax) <- ((crccode) >> 8) & 0x00FFFFFFL
        mov     dx,word ptr DGROUP:_crccode+2
        mov     ax,word ptr DGROUP:_crccode
        mov     al,ah
        mov     ah,dl
        mov     dl,dh
        xor     dh,dh

        mov     bx,di                   ;bx <= i

        mov     bl,byte ptr [bx+si]     ;bl <- buf[i]

        xor     bl,byte ptr DGROUP:_crccode ;bl <- (bl ^ crccode) & 0xff
        xor     bh,bh                   ;bx <- bl
        shl     bx,1
        shl     bx,1                    ;bx <- 4 * bx (for subscript)

        xor     ax,word ptr DGROUP:_crctab[bx]
        xor     dx,word ptr DGROUP:_crctab[bx+2]
        mov     word ptr DGROUP:_crccode+2,dx
        mov     word ptr DGROUP:_crccode,ax

        inc     di              ; i++
        loop    @loop
done:

        pop     di
        pop     si
        mov     sp,bp
        pop     bp
        ret     
_addbfcrc       endp

_TEXT   ends
        end
