I am not a asm freak and i don't realy understand the original source code. But after 4 houres of work it finaly works. ^^
It does not take any advantage of the 64bit architecture. It just works on it.
Have fun using it. And if anyone wants to optimize it, feel free to do, just share the source.

I don't know how to use makros on inline asm, so i solved them. That's why the source code is so big.
And i removed CRC32 check.
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
;64bit code
Procedure.i UnpackMemory_JCalG1(SrcBuffer.i, DestBuffer.i)
Define IndexBase.l ;+64
Define LiteralBits.l ;+72
Define MinimumLiteral.b ;+80
!cld
!push rbx
!push rdi
!push rsi
!mov rsi, [rsp+104] ;SrcBuffer ; rsi->source
!mov rdi, [rsp+112] ;DestBuffer ; rdi->destination
!cmp word [rsi], 'JC' ;check for signature
!jnz UnpMemJc64_DecompDone
!add rsi, 10
!xor ebx, ebx ;zero ebx
!mov edx, 80000000h ;initialize edx, placeholder bit at highest position, force load of new dword.
!mov dword [rsp+64], 8 ;IndexBase,INITIAL_BASE
!inc ebx ;most recently encoded index assumed to be one at start.
!align 4
;the main decompression loop
!UnpMemJc64_DecodeLoop:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload1 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload1:
!jnc UnpMemJc64_IsntLiteral ;if not zero bit, then is not literal
!UnpMemJc64_DoLiteral:
!mov ecx, [rsp+72] ;LiteralBits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop1:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload2 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload2:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop1
!add al, [rsp+80] ;MinimumLiteral
!UnpMemJc64_DecodeZero:
!mov [rdi], al
!inc rdi
!jmp UnpMemJc64_DecodeLoop
!UnpMemJc64_IsntLiteral:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload3 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload3:
!jc UnpMemJc64_NormalPhrase ; if 1, then normal phrase (01)
; else grab next control bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload4 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload4:
!jnc UnpMemJc64_ShortMatch ;if 0, then short phrase (000)
;else, one byte phrase or literal size change
!mov ecx, 4 ;ONEBYTE_PHRASE_BITS
;get one byte phrase index
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop2:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload5 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload5:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop2
!dec eax
!jz UnpMemJc64_DecodeZero
!jns UnpMemJc64_docopy_inc
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload6 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload6:
!jnc UnpMemJc64_GetNewLiteralSize
!UnpMemJc64_NextBlock:
!mov ebp, 256 ;BLOCK_SIZE
!UnpMemJc64_CopyMe:
;_getbyte
!mov ecx, 8 ;8 bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop3:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload7 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload7:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop3
!mov byte [rdi], al
!inc rdi
!dec ebp
!jnz UnpMemJc64_CopyMe
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload8 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload8:
!jc UnpMemJc64_NextBlock
!jmp UnpMemJc64_DecodeLoop
!UnpMemJc64_GetNewLiteralSize:
;retrieve literal information
!mov ecx, 1 ;LITERAL_BITSIZE
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop4:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload9 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload9:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop4
!add eax, 7
!mov [rsp+72], eax
!mov byte [rsp+80], 0
!cmp eax, 8
!jz UnpMemJc64_DecodeLoop
;_getbyte
!mov ecx, 8 ;8 bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop5:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload10 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload10:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop5
!mov [rsp+80], al
!jmp UnpMemJc64_DecodeLoop
!UnpMemJc64_ShortMatch:
!mov ecx, 7 ;SHORT_BITS
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop6:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload11 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload11:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop6
!mov ebp,eax
!mov ecx, 2
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop7:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload12 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload12:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop7
!mov ecx, eax
!mov eax, ebp
!add ecx, 2
!test eax, eax
!jz UnpMemJc64_extendedshort
!mov ebx, eax ;store last used index
!jmp UnpMemJc64_docopy ;go copy the phrase
!UnpMemJc64_extendedshort:
!cmp ecx, 2
!jz UnpMemJc64_DecompDone ;if carry flag nonzero, then decompression finished.
!inc ecx ;3+1=4
;retrieve new index base
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop8:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload13 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload13:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop8
!mov [rsp+64], eax ;store index base
!jmp UnpMemJc64_DecodeLoop ;loop
!UnpMemJc64_NormalPhrase:
;get gamma encoded high index
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc64_getgammaloop1:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload14 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload14:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload15 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload15:
!jc UnpMemJc64_getgammaloop1 ;if one, continue on, if zero, end of integer
!dec ecx ;decrement once
!dec ecx ;decrement twice
!jnz UnpMemJc64_notsamefull ;if not zero, then low bits follow
!mov eax, ebx ;else, index is same as last used
;decode the phrase length
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc64_getgammaloop2:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload16 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload16:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload17 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload17:
!jc UnpMemJc64_getgammaloop2 ;if one, continue on, if zero, end of integer
!jmp UnpMemJc64_docopy ;copy the phrase
!UnpMemJc64_notsamefull:
!dec ecx ;third decrementation
!mov eax, ecx ;store the high bits of index in eax
!mov ecx, [rsp+64] ;ecx=current index base
!mov ebp, eax ;save the high bits of index
!xor eax, eax
!shl ebp, cl ;shift high bits CURRENT_BASE bits lt
;get CURRENT_BASE bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc64_getbitsloop9:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload18 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload18:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc64_getbitsloop9
!or eax, ebp ;or together high and low bits
!mov ebx, eax ;store last used index
;retrieve the phrase length
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc64_getgammaloop3:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload19 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload19:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc64_noload20 ;if not, then return carry bit
!mov edx, dword [rsi]
!add rsi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc64_noload20:
!jc UnpMemJc64_getgammaloop3 ;if one, continue on, if zero, end of integer
;perform index range decremenation
!cmp eax, 010000h ;DecrementIndex3
!jae UnpMemJc64_docopy_threeincs
!cmp eax, 037ffh ;DecrementIndex2
!jae UnpMemJc64_docopy_twoincs
!cmp eax, 027fh ;DecrementIndex1
!jae UnpMemJc64_docopy_inc
!cmp eax, 1111111b ;SHORT_RANGE
!ja UnpMemJc64_docopy
!inc ecx
!UnpMemJc64_docopy_threeincs:
!inc ecx
!UnpMemJc64_docopy_twoincs:
!inc ecx
!UnpMemJc64_docopy_inc:
!inc ecx
!UnpMemJc64_docopy:
!mov rbp, rsi
!mov rsi, rdi ;rsi=P
!sub rsi, rax ;subtract relative index for absolute
!mov r8d, ecx
!shr ecx,2
!rep movsd
!mov ecx, r8d
!and ecx,3
!rep movsb
!mov rsi, rbp
!jmp UnpMemJc64_DecodeLoop ;loop
!UnpMemJc64_DecompDone:
!lea rbp, [rsp+48]
!mov rsi, [rsp+104]
!cmp dword [rsi+6], 0 ;check for checksumme
!jmp UnpMemJc64_DecompGood
!UnpMemJc64_DecompBad:
!XOr rax,rax
!jmp UnpMemJc64_DecompExit
!UnpMemJc64_DecompGood:
!mov rax,rdi ; eax->end of uncompressed data
!sub rax,[rsp+112] ; eax=end of uncompressed data - start of uncompressed Data = size of uncompressed Data
!UnpMemJc64_DecompExit:
!pop rsi
!pop rdi
!pop rbx
ProcedureReturn
EndProcedure
CompilerElse
;32bit code
Procedure.i UnpackMemory_JCalG1(SrcBuffer.i, DestBuffer.i)
Define IndexBase.l ;+12
Define LiteralBits.l ;+16
Define MinimumLiteral.b ;+20
!cld
!push ebx
!push edi
!push esi
!mov esi, [esp+28] ;SrcBuffer ; rsi->source
!mov edi, [esp+32] ;DestBuffer ; rdi->destination
!cmp word [esi], 'JC' ;check for signature
!jnz UnpMemJc32_DecompDone
!add esi, 10
!xor ebx, ebx ;zero ebx
!mov edx, 80000000h ;initialize edx, placeholder bit at highest position, force load of new dword.
!mov dword [esp+12], 8 ;IndexBase,INITIAL_BASE
!inc ebx ;most recently encoded index assumed to be one at start.
!align 4
;the main decompression loop
!UnpMemJc32_DecodeLoop:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload1 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload1:
!jnc UnpMemJc32_IsntLiteral ;if not zero bit, then is not literal
!UnpMemJc32_DoLiteral:
!mov ecx, [esp+16] ;LiteralBits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop1:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload2 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload2:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop1
!add al, [esp+20] ;MinimumLiteral
!UnpMemJc32_DecodeZero:
!mov [edi], al
!inc edi
!jmp UnpMemJc32_DecodeLoop
!UnpMemJc32_IsntLiteral:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload3 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload3:
!jc UnpMemJc32_NormalPhrase ; if 1, then normal phrase (01)
; else grab next control bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload4 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload4:
!jnc UnpMemJc32_ShortMatch ;if 0, then short phrase (000)
;else, one byte phrase or literal size change
!mov ecx, 4 ;ONEBYTE_PHRASE_BITS
;get one byte phrase index
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop2:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload5 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload5:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop2
!dec eax
!jz UnpMemJc32_DecodeZero
!jns UnpMemJc32_docopy_inc
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload6 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload6:
!jnc UnpMemJc32_GetNewLiteralSize
!UnpMemJc32_NextBlock:
!mov ebp, 256 ;BLOCK_SIZE
!UnpMemJc32_CopyMe:
;_getbyte
!mov ecx, 8 ;8 bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop3:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload7 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload7:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop3
!mov byte [edi], al
!inc edi
!dec ebp
!jnz UnpMemJc32_CopyMe
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload8 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload8:
!jc UnpMemJc32_NextBlock
!jmp UnpMemJc32_DecodeLoop
!UnpMemJc32_GetNewLiteralSize:
;retrieve literal information
!mov ecx, 1 ;LITERAL_BITSIZE
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop4:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload9 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload9:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop4
!add eax, 7
!mov [esp+16], eax
!mov byte [esp+20], 0
!cmp eax, 8
!jz UnpMemJc32_DecodeLoop
;_getbyte
!mov ecx, 8 ;8 bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop5:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload10 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload10:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop5
!mov [esp+20], al
!jmp UnpMemJc32_DecodeLoop
!UnpMemJc32_ShortMatch:
!mov ecx, 7 ;SHORT_BITS
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop6:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload11 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload11:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop6
!mov ebp,eax
!mov ecx, 2
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop7:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload12 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload12:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop7
!mov ecx, eax
!mov eax, ebp
!add ecx, 2
!test eax, eax
!jz UnpMemJc32_extendedshort
!mov ebx, eax ;store last used index
!jmp UnpMemJc32_docopy ;go copy the phrase
!UnpMemJc32_extendedshort:
!cmp ecx, 2
!jz UnpMemJc32_DecompDone ;if carry flag nonzero, then decompression finished.
!inc ecx ;3+1=4
;retrieve new index base
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop8:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload13 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload13:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop8
!mov [esp+12], eax ;store index base
!jmp UnpMemJc32_DecodeLoop ;loop
!UnpMemJc32_NormalPhrase:
;get gamma encoded high index
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc32_getgammaloop1:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload14 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload14:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload15 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload15:
!jc UnpMemJc32_getgammaloop1 ;if one, continue on, if zero, end of integer
!dec ecx ;decrement once
!dec ecx ;decrement twice
!jnz UnpMemJc32_notsamefull ;if not zero, then low bits follow
!mov eax, ebx ;else, index is same as last used
;decode the phrase length
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc32_getgammaloop2:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload16 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload16:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload17 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload17:
!jc UnpMemJc32_getgammaloop2 ;if one, continue on, if zero, end of integer
!jmp UnpMemJc32_docopy ;copy the phrase
!UnpMemJc32_notsamefull:
!dec ecx ;third decrementation
!mov eax, ecx ;store the high bits of index in eax
!mov ecx, [esp+12] ;ecx=current index base
!mov ebp, eax ;save the high bits of index
!xor eax, eax
!shl ebp, cl ;shift high bits CURRENT_BASE bits lt
;get CURRENT_BASE bits
;_getbits
!xor eax, eax
!align 4
!UnpMemJc32_getbitsloop9:
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload18 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload18:
!adc eax,eax ;add bit to eax
!dec ecx
!jnz UnpMemJc32_getbitsloop9
!or eax, ebp ;or together high and low bits
!mov ebx, eax ;store last used index
;retrieve the phrase length
;_getgamma
!mov ecx, 1
!align 4
!UnpMemJc32_getgammaloop3:
;retrieve a bit from the input stream
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload19 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload19:
!adc ecx, ecx ;add it to destination
;retrieve another bit
;_getbit
!add edx, edx ;edx*2, equiv. to shl edx,1 if placeholder bit (1) is shifted off into carry then result is zero.
!jnz UnpMemJc32_noload20 ;if not, then return carry bit
!mov edx, dword [esi]
!add esi, 4
!stc
!adc edx, edx ;minimum value now one, lowest bit used as placeholder, highest bit shifted off for return
!UnpMemJc32_noload20:
!jc UnpMemJc32_getgammaloop3 ;if one, continue on, if zero, end of integer
;perform index range decremenation
!cmp eax, 010000h ;DecrementIndex3
!jae UnpMemJc32_docopy_threeincs
!cmp eax, 037ffh ;DecrementIndex2
!jae UnpMemJc32_docopy_twoincs
!cmp eax, 027fh ;DecrementIndex1
!jae UnpMemJc32_docopy_inc
!cmp eax, 1111111b ;SHORT_RANGE
!ja UnpMemJc32_docopy
!inc ecx
!UnpMemJc32_docopy_threeincs:
!inc ecx
!UnpMemJc32_docopy_twoincs:
!inc ecx
!UnpMemJc32_docopy_inc:
!inc ecx
!UnpMemJc32_docopy:
!mov ebp, esi
!mov esi, edi ;esi=P
!sub esi, eax ;subtract relative index for absolute
!push ecx
!shr ecx,2
!rep movsd
!pop ecx
!and ecx,3
!rep movsb
!mov esi, ebp
!jmp UnpMemJc32_DecodeLoop ;loop
!UnpMemJc32_DecompDone:
!lea ebp, [esp+24]
!mov esi, [esp+28]
!cmp dword [esi+6], 0 ;check for checksumme
!jmp UnpMemJc32_DecompGood
!UnpMemJc32_DecompBad:
!xor eax, eax
!jmp UnpMemJc32_DecompExit
!UnpMemJc32_DecompGood:
!mov eax,edi ; eax->end of uncompressed data
!sub eax,[esp+32] ; eax=end of uncompressed data - start of uncompressed Data = size of uncompressed Data
!UnpMemJc32_DecompExit:
!pop esi
!pop edi
!pop ebx
ProcedureReturn
EndProcedure
CompilerEndIf