⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode_c.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
字号:
decode_c_struc struc
DecC_ID db "CWC"
DecC_Bits       db 0
DecC_Len        dd ?
DecC_Size       dd ?
decode_c_struc  ends


RepMinSize      equ     2


;
;Get next input bit.
;
_DCD_ReadBit    macro
        local __0
        adc     ebp,ebp
        dec     dl
        jnz     __0
        mov     ebp,[esi]
        lea     esi,4[esi]
        mov     dl,dh
__0:    ;
        endm


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;Return expanded length of a CWC'd file.
;
;On Entry:
;
;BX     - File handle.
;
;Carry set on error else,
;
;ECX    - Expanded data length.
;EDX    - Compressed data length.
;
GetCWCInfo      proc    near
        pushm   ebx,edx,esi,edi,ebp,ds
        assume ds:nothing
        mov     ds,cs:apiDDSeg
        assume ds:_apiCode
        ;
        ;Get current file pointer position.
        ;
        mov     ax,4201h
        xor     cx,cx
        xor     dx,dx
        int     21h
        mov     w[decode_c_count],ax
        mov     w[decode_c_count+2],dx
        ;
        ;Read the header.
        ;
        mov     edx,offset decode_c_head

; MED 12/18/96, as per JW
        xor     ecx,ecx
        mov     cx,size decode_c_struc

        mov     ah,3fh
        int     21h
        jc      @@error
        cmp     ax,cx
        jnz     @@error
        ;
        ;Check for main ID string.
        ;
        mov     eax,d[decode_c_head+DecC_ID]
        and     eax,0FFFFFFh
        cmp     eax,"CWC"
        jnz     @@error
        mov     ecx,d[decode_c_head+DecC_Len]
        mov     eax,d[decode_c_head+DecC_Size]
        add     eax,size decode_c_struc
        clc
        jmp     @@exit
        ;
@@error:        stc
        ;
@@exit: pushf
        pushm   eax,ecx
        mov     ax,4200h
        mov     dx,w[decode_c_count]
        mov     cx,w[decode_c_count+2]
        int     21h
        popm    eax,ecx
        popf
        popm    ebx,edx,esi,edi,ebp,ds
        ret
GetCWCInfo      endp


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
;
;Decompress CWC file. Source is a file on disk, destination is anywhere in
;memory.
;
;On Entry:-
;
;BX     - Source File Handle.
;ES:EDI - Destination for data.
;
;On Exit:-
;
;EAX    - Exit status.
;       0 = No problems
;       1 = Error during file access.
;       2 = Bad data.
;       3 = Not a CWC'd file.
;
;ECX    - Length of data produced.
;
DecodeCWC       proc    near
        cld
        pushm   ebx,edx,esi,edi,ebp,ds,es,fs,gs
        assume ds:nothing
        mov     ds,cs:apiDDSeg
        assume ds:_apiCode
        mov     CWCStack,esp            ;Set for error exit.
        mov     Decode_c_Handle,bx      ;Store the handle.
        mov     d[OutAddr],edi  ;Store destination.
        mov     w[OutAddr+4],es ;/
;
;Setup disk buffer variables.
;
        push    ds
        mov     ds,apiDSeg
        assume ds:_cwMain
        mov     ds,PSPSegment
        assume ds:nothing
        mov     ecx,ds:d[EPSP_TransSize]
        mov     ax,ds:w[EPSP_TransProt]
        mov     bx,ds:w[EPSP_TransReal]
        assume ds:_apiCode
        pop     ds
        mov     cDiskBufferMax,ecx
        mov     cDiskBufferSeg,ax
        mov     cDiskBufferReal,bx
;
;Get the header so we can check which type it is.
;
        mov     edx,offset decode_c_head
        mov     cx,size decode_c_struc
        mov     ah,3fh
        mov     bx,decode_c_handle
        int     21h
        jc      @@read_error
        cmp     ax,cx
        jnz     @@read_error
        mov     decode_c_count,0        ;size decode_c_struc
        ;
        ;Check for main ID string.
        ;
        mov     eax,d[decode_c_head+DecC_ID]
        and     eax,0FFFFFFh
        cmp     eax,"CWC"
        jnz     @@cwc_error
        movzx   ecx,b[decode_c_head+DecC_Bits]
        mov     b[@@Shifter+2],cl
        mov     eax,1
        shl     eax,cl
        dec     eax
        mov     d[@@Masker+2],eax
        mov     ebx,d[decode_c_head+DecC_Len]
;
;Get on with decodeing the data.
;
        les     edi,OutAddr
        mov     ds,cDiskBufferSeg
        xor     esi,esi
        call    @@FillBuffer
        mov     ebp,[esi]
        add     esi,4
        mov     dl,32
        mov     dh,dl
;
;The main decompresion loop.
;
        align 4
@@0:    _DCD_ReadBit
        jnc     @@1
        ;
        ;Read a raw byte.
        ;
        mov     al,[esi]
        mov     es:[edi],al
        inc     esi
        inc     edi
        dec     ebx
        js      @@4
        jmp     @@0
        ;
        align 4
@@1:    _DCD_ReadBit
        jnc     @@2
        ;
        ;Do a rep with 8 bit position, 2 bit length.
        ;
        xor     ecx,ecx
        _DCD_ReadBit
        adc     cl,cl
        _DCD_ReadBit
        adc     cl,cl
        add     cl,2
        xor     eax,eax
        mov     al,[esi]
        inc     esi
        dec     eax
        js      @@1_0
        add     eax,ecx
        pushm   esi,ds,es
        pop     ds
        mov     esi,edi
        sub     esi,eax
        sub     ebx,ecx
        js      @@4
        rep     movsb
        popm    esi,ds
        jmp     @@0
        ;
        ;Do a run with 2 bit length.
        ;
        align 4
@@1_0:  mov     al,[esi]
        inc     esi
        inc     cl
        sub     ebx,ecx
        js      @@4
        rep     stosb
        jmp     @@0
        ;
        align 4
@@2:    _DCD_ReadBit
        jnc     @@3
        ;
        ;Do a rep with 12 bit position, 4 bit length.
        ;
        xor     eax,eax
        mov     ax,[esi]
        add     esi,2
        mov     cl,al
        and     ecx,15
        add     cl,2
        shr     eax,4
        dec     eax
        js      @@2_0
        add     eax,ecx
        pushm   esi,ds,es
        pop     ds
        mov     esi,edi
        sub     esi,eax
        sub     ebx,ecx
        js      @@4
        rep     movsb
        popm    esi,ds
        jmp     @@0
        ;
        ;Do a run with 4 bit length.
        ;
        align 4
@@2_0:  mov     al,[esi]
        inc     esi
        inc     cl
        sub     ebx,ecx
        js      @@4
        rep     stosb
        jmp     @@0
        ;
        ;Do a rep with 12-bit position, 12-bit length.
        ;
        align 4
@@3:    mov     eax,[esi]
        add     esi,3
        and     eax,0FFFFFFh
        mov     ecx,eax
@@Masker:       and     ecx,4095
        add     ecx,2
@@Shifter:      shr     eax,12
        dec     eax
        js      @@3_0
        add     eax,ecx
        pushm   esi,ds,es
        pop     ds
        mov     esi,edi
        sub     esi,eax
        sub     ebx,ecx
        js      @@4
        rep     movsb
        popm    esi,ds
        jmp     @@0
        ;
        ;Check for special codes of 0-15 (Would use 2 or 4 bit if really needed)
        ;
        align 4
@@3_0:  cmp     ecx,RepMinSize+15+1
        jnc     @@3_1
        cmp     cl,RepMinSize+2 ;Rationalise destination?
        jz      @@0             ;ignore destination stuff.
        cmp     cl,RepMinSize+1 ;Re-fill buffer?
        jz      @@3_2
        cmp     cl,RepMinSize+3 ;Literal string?
        jz      @@3_3
        cmp     cl,RepMinSize   ;Terminator?
        jz      @@4
        jmp     @@form_error
        ;
        ;Do a run with 12-bit length.
        ;
        align 4
@@3_1:  mov     al,[esi]
        inc     esi
        inc     ecx
        sub     ebx,ecx
        js      @@4
        rep     stosb
        jmp     @@0
        ;
        ;Buffer needs to be re-filled.
        ;
        align 4
@@3_2:  call    @@FillBuffer
        jmp     @@0
        ;
        ;Get literal string of bytes.
        ;
        align 4
@@3_3:  xor     ecx,ecx
        mov     cl,[esi]                ;get the length.
        inc     esi
        sub     ebx,ecx
        js      @@4
        rep     movsb           ;copy them.
        jmp     @@0
        ;
        ;We're all done so exit.
        ;
        align 4
@@4:    assume ds:nothing
        ;
        or      ebx,ebx
        jnz     @@form_error
        ;
        mov     ecx,cs:d[decode_c_head+DecC_Len]        ;return length.
        xor     eax,eax
        clc
        jmp     @@exit
        ;
@@read_error:   mov     eax,1
        stc
        jmp     @@exit
        ;
@@form_error:   mov     eax,2
        stc
        jmp     @@exit
        ;
@@cwc_error:    assume ds:nothing
        mov     ds,cs:apiDDSeg
        assume ds:_apiCode
        mov     bx,decode_c_handle
        mov     ax,4001h
        mov     dx,-(size decode_c_struc)
        or      cx,-1
        int     21h
        mov     eax,3
        stc
        assume ds:nothing
        ;
@@exit: mov     esp,cs:CWCStack
        popm    ebx,edx,esi,edi,ebp,ds,es,fs,gs
        ret
;
;Re-fill the disk buffer.
;
@@FillBuffer:   pushad
        pushm   ds,es
        mov     ds,cs:apiDDSeg
        assume ds:_apiCode
        push    ds
        pop     es
        ;
        mov     ecx,cDiskBufferMax      ;get block size.
        or      esi,esi
        jz      @@fb0
        ;
        sub     ecx,esi         ;get length still in the buffer.
        xor     edi,edi
        pushm   ecx,esi,ds,es
        mov     ds,cDiskBufferSeg
        push    ds
        pop     es
        rep     movsb           ;copy remaining data down.
        popm    ecx,esi,ds,es
        xchg    esi,ecx
        ;
@@fb0:  mov     edi,offset decode_c_buffer
        mov     eax,decode_c_count      ;get current count.
        add     eax,ecx
        cmp     eax,d[decode_c_head+DecC_Size]  ;check against total size.
        jc      @@FB_2
        sub     eax,d[decode_c_head+DecC_Size]
        sub     ecx,eax         ;reduce ECX as needed.
@@FB_2: add     decode_c_count,ecx      ;update total count.
        ;
        mov     Real_ECX[edi],ecx
        mov     ax,cDiskBufferReal
        mov     Real_DS[edi],ax
        mov     Real_EDX[edi],esi
        mov     Real_EAX[edi],3f00h
        mov     ax,decode_c_handle
        mov     Real_EBX[edi],eax
        mov     bl,21h
        sys     IntXX           ;fill the buffer again.
        test    Real_Flags[edi],1
        jnz     @@read_error
        mov     eax,Real_EAX[edi]
        mov     ecx,Real_ECX[edi]
        cmp     ax,cx
        jnz     @@read_error
        popm    ds,es
        popad
        xor     esi,esi
        ret
        assume ds:_apiCode
DecodeCWC       endp

;
        align 4
cDiskBufferMax  dd ?
cDiskBufferSeg  dw ?
cDiskBufferReal dw ?
;
decode_c_count  dd ?
CWCStack        dd ?
;
OutAddr df ?
decode_c_handle dw ?
;
        align 4
decode_c_Buffer db size v86CallStruc dup (?)
;
        align 4
decode_c_head   decode_c_struc <>
;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -