| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- (*
- Copyright (C) 1989,1990 Jensen & Partners International
- *)
- module apack2
- stats? = 0 (* count hash collisions and table resets *)
- reset? = 1 (* possible values are 0,1 *)
- ebit = 3 (* possible values are 0,1,3 *)
- buf_size = 3800H
- shift2 = ebit & 1
- shift4 = ( ebit & 2 ) / 2
- period = 8 / (ebit+1)
- max_hash = power2 (ebit+10 ) - 1
- max_code = power2 (ebit+9 ) - 1
- re_hash = 113
- segment APACK2_DATA(FAR_DATA,28H)
- public apack2@prfx: org 2*(max_hash+1) + 4 (* must be at 0 in actual segment !! *)
- prfx = 0
- public apack2@reset_count: org 2
- public apack2@collision_count : org 2
- public lim: org 2 (* limit for si *)
- public apack2@p: org (buf_size/8) * ( 9 + ebit )
- public char: org max_hash+1 + 2
- public code: org 2*(max_hash+1) + 4
- segment APACK2_TEXT( CODE, 28H )
- ClearTable:
- push ax; push cx; push di; push es
- push ds; pop es
- mov di, prfx
- mov cx, max_hash+1
- mov ax, -1
- rep; stosw
- pop es; pop di; pop cx; pop ax
- ret 0
- public apack2$Pack: in = 6 ; n = 10
- (* Current register usage:
- al : input char
- ah : zero
- bx : hash table index
- cl : free bit count for ch
- ch : holds extra bits
- dx : current code or 256+number of codes output since reset
- es:si : input pointer
- ds:di : output pointer
- *)
- push bp
- mov bp, sp
- push si; push di; push ds; push es
- mov ax, APACK2_DATA
- mov ds, ax
- (*%T stats?*)
- mov word [apack2@reset_count], 0
- mov word [apack2@collision_count],0
- (*%E*)
- call ClearTable
- les si, [bp][in]
- mov dx, si
- add dx,[bp][n]
- mov [lim],dx
- db 26H; lodsb
- sub ah,ah
- mov dx,ax
- mov word bp, 256
- mov di, apack2@p+1
- mov ch,0
- mov cl,period
- jmp loop1
- shift_zero:
- mov [di][-(period+1)], ch
- inc di
- mov cx,period
- (*%F reset?*)
- cmp bp, max_code
- jne shift_zero_done
- mov bp,[lim]
- jmp near _output_done
- (*%E*)
- (*%T reset?*)
- jmp shift_zero_done
- (*%E*)
- (*%T reset?*)
- clear:
- (*%T stats?*) inc word [apack2@reset_count] (*%E*)
- call ClearTable
- mov bp, 256
- jmp output_done
- (*%E*)
- else1:
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- shl bx, 1
- add bx, re_hash*2
- jmp loop2
- exit1x:
- jmp near exit1
- match:
- shr bx,1
- cmp[char][bx], al
- jne else1
- shl bx,1
- mov dx, [code][bx]
- (*jmp loop1*) (*unrolled once*)
- cmp si,[lim]
- je exit1x
- db 26H; lodsb
- mov bx,dx
- add bl,al
- add bh,al
- (*loop2:*)
- and bx, max_hash*2
- cmp [prfx][bx], dx
- je match
- cmp word [prfx][bx],-1
- jne collide
- output:
- shl ch,1
- (*%T shift2*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- add ch, dh
- mov [di], dl
- inc di
- dec cl
- jz shift_zero
- shift_zero_done:
- mov [prfx][bx],dx
- mov [code][bx],bp
- shr bx,1
- mov [char][bx],al
- inc bp
- (*%T reset?*)
- cmp bp, max_code+1
- je clear
- (*%E*)
- output_done:
- mov dx,ax
- loop1:
- cmp si,[lim]
- je exit1
- db 26H; lodsb
- mov bx,dx
- add bl,al
- add bh,al
- loop2:
- and bx, max_hash*2
- cmp word [prfx][bx],-1
- je output
- cmp [prfx][bx], dx
- je match
- collide:
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- (*jmp loop2*) (*unroll 1*)
- and bh, max_hash / 128
- cmp word [prfx][bx],-1
- je output
- cmp [prfx][bx], dx
- je match
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- (*jmp loop2*) (*unroll 2*)
- and bh, max_hash / 128
- cmp word [prfx][bx],-1
- je output
- cmp [prfx][bx], dx
- je match
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- jmp loop2 (*end unroll*)
- exit1:
- shl ch,1
- (*%T shift2*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- add ch, dh
- mov [di], dl
- inc di
- dec cl
- mov ax, di
- sub ax, apack2@p
- mov dl, ch
- sub ch,ch
- add di,cx
- (*%T shift2*) shl cl,1 (*%E*)
- (*%T shift4*) shl cl,1 (*%E*)
- shl dl,cl
- mov [di][-(period+1)], dl
- pop es; pop ds; pop di; pop si
- pop bp;
- ret far 6
- (*%F reset?*)
- _shift_zero:
- mov [di][-(period+1)], ch
- inc di
- mov cx,period
- jmp _shift_zero_done
- _else1:
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- shl bx, 1
- add bx, re_hash*2
- jmp _loop2
- _exit1:
- jmp exit1
- _match:
- shr bx,1
- cmp[char][bx], al
- jne _else1
- shl bx,1
- mov dx, [code][bx]
- (*jmp _loop1*) (* unrolled copy of loop1*)
- cmp si,bp
- je exit1
- db 26H; lodsb
- mov bx,dx
- add bl,al
- add bh,al
- (*_loop2:*)
- and bx, max_hash*2
- cmp [prfx][bx], dx
- je _match
- cmp word [prfx][bx],-1
- jne _collide
- _output:
- shl ch,1
- (*%T shift2*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- (*%T shift4*) shl ch,1 (*%E*)
- add ch, dh
- mov [di], dl
- inc di
- dec cl
- jz _shift_zero
- _shift_zero_done:
- _output_done:
- mov dx,ax
- _loop1:
- cmp si,bp
- je _exit1
- db 26H; lodsb
- mov bx,dx
- add bl,al
- add bh,al
- _loop2:
- and bx, max_hash*2
- cmp word [prfx][bx],-1
- je _output
- cmp [prfx][bx], dx
- je _match
- _collide:
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- (*jmp loop2*) (*unroll 1*)
- and bh, max_hash / 128
- cmp word [prfx][bx],-1
- je _output
- cmp [prfx][bx], dx
- je _match
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- (*jmp loop2*) (*unroll 2*)
- and bh, max_hash / 128
- cmp word [prfx][bx],-1
- je _output
- cmp [prfx][bx], dx
- je _match
- (*%T stats?*) inc word [apack2@collision_count] (*%E*)
- add bx, re_hash*2
- jmp _loop2 (*end unroll*)
- (*%E*) (*reset?*)
- errmsg: db 'Unpack error'
- public apack2$Unpack: out = 16; n = 20
- k = 10
- sub sp, 2
- push si; push di; push ds; push es
- push bp
- mov bp,sp
- mov ax, APACK2_DATA ; mov ds, ax
- les di, [bp][out]
- add [bp][n], di
- mov si, apack2@p
- (* new shift *)
- mov cl,period
- mov ch,[si]
- inc si
- (* get first code *)
- lodsb
- sub ah,ah
- shl ch,1 ; rcl ah,1
- (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- (* reset *)
- mov bx, 256
- mov [code][512],ax
- mov [bp][k],al
- stosb
- jmp uloop1
- more:
- pop ax
- stosw
- uloop1:
- cmp sp, bp
- jne more
- cmp di, [bp][n]
- jae uexit1
- dec cl
- jz new_shift
- new_shift_done:
- lodsb
- sub ah,ah
- shl ch,1 ; rcl ah,1
- (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- (*%T reset?*)
- cmp bx, max_code
- je reset
- (*%E*)
- mov dx,bx
- shl bx,1
- mov [code][bx][2],ax
- cmp ax,dx
- jae special_case
- mov bx,ax
- uloop22_test:
- cmp bx, 256
- jae uloop21
- mov [bp][k], bx
- mov al, bl
- stosb
- xchg bx,dx
- (*%F reset?*)
- cmp bx, max_code+1
- je _uloop1
- (*%E*)
- mov [char][bx],dl
- inc bx
- jmp uloop1
- uloop21:
- mov ah, [char][bx]
- shl bx,1
- mov bx, [code][bx]
- uloop21_test:
- cmp bx, 256
- jae uloop2_continue
- mov [bp][k], bx
- mov al,bl
- stosw
- xchg bx,dx
- (*%F reset?*)
- cmp bx, max_code+1
- je _uloop1
- (*%E*)
- mov [char][bx],dl
- inc bx
- jmp uloop1
- uloop2_continue:
- mov al, [char][bx]
- push ax
- shl bx,1
- mov bx, [code][bx]
- jmp uloop22_test
- new_shift:
- mov cl,period
- mov ch,[si]
- inc si
- jmp new_shift_done
- uexit1:
- ja unpack_error
- pop bp
- pop es; pop ds; pop di; pop si
- add sp, 2
- ret far 6
- (*%T reset?*)
- reset:
- mov bx, 256
- mov [code][512],ax
- mov [bp][k],al
- stosb
- jmp uloop1
- (*%E*)
- special_case:
- ja unpack_error
- mov ah, [bp][k]
- mov bx, [code][bx]
- jmp uloop21_test
- unpack_error:
- (*
- mov ax, unpack_error - errmsg
- push ax
- mov ax, errmsg
- push cs
- push ax
- extrn AsmLib$FatalError
- call far AsmLib$FatalError
- *)
- (**)
- xor ax,ax
- push ax
- push ax
- push ax
- extrn __FatalError
- call far __FatalError
- (**)
- (*%F reset?*)
- _more:
- pop ax
- stosw
- _uloop1:
- cmp sp, bp
- jne _more
- cmp di, [bp][n]
- jae uexit1
- dec cl
- jz _new_shift
- _new_shift_done:
- lodsb
- sub ah,ah
- shl ch,1 ; rcl ah,1
- (*%T shift2*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- (*%T shift4*) shl ch,1; rcl ah,1 (*%E*)
- mov dx,bx
- shl bx,1
- mov [code][bx][2],ax
- cmp ax,dx
- jae _special_case
- mov bx,ax
- _uloop22_test:
- cmp bx, 256
- jae _uloop21
- mov [bp][k], bx
- mov al, bl
- stosb
- xchg bx,dx
- jmp _uloop1
- _uloop21:
- mov ah, [char][bx]
- shl bx,1
- mov bx, [code][bx]
- _uloop21_test:
- cmp bx, 256
- jae _uloop2_continue
- mov [bp][k], bx
- mov al,bl
- stosw
- xchg bx,dx
- jmp _uloop1
- _uloop2_continue:
- mov al, [char][bx]
- push ax
- shl bx,1
- mov bx, [code][bx]
- jmp _uloop22_test
- _new_shift:
- mov cl,period
- mov ch,[si]
- inc si
- jmp _new_shift_done
- _special_case:
- ja unpack_error
- mov ah, [bp][k]
- mov bx, [code][bx]
- jmp _uloop21_test
- (*%E*) (* reset? *)
- end
|