Category : C Source Code
Archive   : LH113SRC.ZIP
Filename : LZS.ASM
Output of file : LZS.ASM contained in archive : LH113SRC.ZIP
;$_init
;***********************************************;
; LHarc version 1.13b (c) Yoshi 1988-89.
; LZSS module : 1989/ 5/14
;
;
; HTAB = 8
;***********************************************;
extrn __fgetc:near
extrn __fputc:near
;***************************************
; getc macro
; bx: address of FILE struc
; ax: input char (return)
;***************************************
getc@ macro
local getc1, getc2
dec word ptr [bx]
jl getc1
inc word ptr [bx+10]
mov bx, [bx+10]
mov al, [bx-1]
xor ah, ah
jmp getc2
getc1:
push dx
push cx
push bx
call __fgetc
pop bx
pop cx
pop dx
getc2:
endm
getc_crc@ macro
local getc1, getc2
dec word ptr [bx]
jl getc1
inc word ptr [bx+10]
mov bx, [bx+10]
mov al, [bx-1]
xor ah, ah
jmp getc2
getc1:
call crcgetc
getc2:
endm
;***************************************
; putc macro
; ax: output char
; bx: address of FILE struc
;***************************************
putc@ macro
local putc1, putc2
inc word ptr [bx]
jge putc1
inc word ptr [bx+10]
mov bx, [bx+10]
mov [bx-1], al
jmp short putc2
putc1:
call fputc
putc2:
endm
putc_crc@ macro
local putc1, putc2
inc word ptr [bx]
jge putc1
inc word ptr [bx+10]
mov bx, [bx+10]
mov [bx-1], al
jmp short putc2
putc1:
call crcputc
putc2:
endm
DGROUP group _DATA,_BSS
EGROUP group _EXTRA
name lzsub
_TEXT segment byte public 'CODE'
assume cs:_TEXT,ds:DGROUP,es:EGROUP,ss:DGROUP
_TEXT ends
_DATA segment word public 'DATA'
mark db 'o'
_DATA ends
_BSS segment word public 'BSS'
_BSS ends
_EXTRA segment word public
_EXTRA ends
_TEXT segment
extrn DGROUP@ :word
extrn _outfile :word
extrn _infname :word
extrn _outfname :word
extrn _codesize :word
extrn _crc :word
extrn _copying :byte
extrn _crcflg :byte
extrn _tstflg :byte
extrn _error :near
extrn _ftell :near
extrn _fseek :near
N equ 4096
F equ 60
THRESHOLD equ 2
NIL equ N
ROOTMK equ -1
F_OLD equ 18
public _text_buf, _match_position, _match_length
public _rson, _lson, _dad, _root, _buf2, _buf3
public len
public crctbl
public extra
_BSS segment
crctbl dw 100h dup (?)
extra dw 1 dup (?)
_match_position dw 1 dup (?)
_match_length dw 1 dup (?)
len dw 1 dup (?)
_buf2 db 4096 dup (?)
_buf3 db 4096 dup (?)
_rson dw (N + 1) dup (?)
_lson dw (N + 1) dup (?)
_dad dw (N + 1) dup (?)
_root dw (N + 1) dup (?)
_text_buf db (N + F - 1) dup (?)
_BSS ends
;-----------------------------------------------;
public _InitTree
_InitTree proc near
push di
mov bx, 1000h
mov ah, 48h ; get memory
int 21h
jNC $_1
xor ax, ax
push ax
mov ax, 15 ; MEMOVRERR
push ax
call _error
$_1:
mov DGROUP:extra, ax
cld
mov es, ax
mov ax, NIL * 2
mov cx, 8000h
mov di, 0
rep stosw
mov bx, ds
mov es, bx
mov cx, N
mov di, offset DGROUP:_dad
rep stosw
pop di
ret
_InitTree endp
;-----------------------------------------------;
public _InsertNode
_InsertNode proc near
push si
push di
mov es, DGROUP:extra
mov bx, di ; di = r
shl bx, 1
add di, offset DGROUP:_text_buf
mov ax, [di]
xor ah, [di + 2]
shl ax, 1 ; si = p
mov si, ax
mov ax, NIL * 2
mov DGROUP:_rson[bx], ax
mov DGROUP:_lson[bx], ax
cmp word ptr EGROUP:[si], ax ; NIL * 2
jne in10
mov EGROUP:[si], bx
mov DGROUP:_dad[bx], ROOTMK
mov DGROUP:_root[bx], si
jmp in9
in10: mov bp, EGROUP:[si]
mov cx, ds
mov es, cx
cld
inc di
mov dx, di
; $_while TRUE
in11: mov di, dx
mov si, bp
shr si, 1
add si, offset DGROUP:_text_buf + 1
mov cx, F-1
repe cmpsb
mov si, bp
je in7
in0: ja in2
mov bp, DGROUP:_rson[si]
cmp bp, ax ; NIL * 2
jne in11
mov DGROUP:_rson[si], bx
mov DGROUP:_dad[bx], si
jmp in9 ;
in2: mov bp, DGROUP:_lson[si]
cmp bp, ax ; NIL * 2
jne in11
mov DGROUP:_lson[si], bx
mov DGROUP:_dad[bx], si
jmp in9
; $_enddo
in7: mov di, DGROUP:_lson[si]
mov DGROUP:_dad[di], bx
mov DGROUP:_lson[bx], di
mov di, DGROUP:_rson[si]
mov DGROUP:_dad[di], bx
mov DGROUP:_rson[bx], di
mov di, DGROUP:_dad[si]
mov DGROUP:_dad[bx], di
mov word ptr DGROUP:_dad[si], ax ; NIL * 2
or di, di
jNS $_2
; ROOTMK
mov es, DGROUP:extra
mov di, DGROUP:_root[si]
mov DGROUP:_root[bx], di
mov EGROUP:[di], bx
jmp short in9
$_2: cmp DGROUP:_rson[di], si
jNE $_3
mov DGROUP:_rson[di], bx
jmp short $_4
$_3: mov DGROUP:_lson[di], bx
$_4:
in9: pop di
pop si
ret
_InsertNode endp
;-----------------------------------------------;
public _MatchInsertNode
_MatchInsertNode proc near
push si
push di
mov es, DGROUP:extra
mov bx, di ; di = r
shl bx, 1
add di, offset DGROUP:_text_buf
mov ax, [di]
xor ah, [di + 2]
shl ax, 1 ; si = p
mov si, ax
mov ax, NIL * 2
mov DGROUP:_rson[bx], ax
mov DGROUP:_lson[bx], ax
mov al, F - 1
cmp word ptr EGROUP:[si], NIL * 2
jne min10
mov EGROUP:[si], bx
mov DGROUP:_dad[bx], ROOTMK
mov DGROUP:_root[bx], si
jmp min9
min10: mov bp, EGROUP:[si]
mov cx, ds
mov es, cx
cld
inc di
mov dx, di
; $_while TRUE
min11: mov di, dx
mov si, bp
shr si, 1
add si, offset DGROUP:_text_buf + 1
mov cx, F - 1
repe cmpsb
lahf
je min7
cmp cx, F - THRESHOLD - 1
jge min0
cmp cl, al
jg min0
je min5
mov al, cl
sub di, si
and di, N - 1
mov DGROUP:_match_position, di
jmp min0
min5: sub di, si
and di, N - 1
cmp di, DGROUP:_match_position
jge min6
mov DGROUP:_match_position, di
min6:
min0: mov si, bp
sahf
ja min2
mov bp, DGROUP:_rson[si]
cmp bp, NIL * 2
jne min11
mov DGROUP:_rson[si], bx
mov DGROUP:_dad[bx], si
jmp min9
min2: mov bp, DGROUP:_lson[si]
cmp bp, NIL * 2
jne min11
mov DGROUP:_lson[si], bx
mov DGROUP:_dad[bx], si
jmp min9
; $_enddo
min7:
mov al, -1
sub di, si
and di, N - 1
mov DGROUP:_match_position, di
mov si, bp
mov di, DGROUP:_lson[si]
mov DGROUP:_dad[di], bx
mov DGROUP:_lson[bx], di
mov di, DGROUP:_rson[si]
mov DGROUP:_dad[di], bx
mov DGROUP:_rson[bx], di
mov di, DGROUP:_dad[si]
mov DGROUP:_dad[bx], di
mov word ptr DGROUP:_dad[si], NIL * 2
or di, di
jNS $_5
mov es, DGROUP:extra
mov di, DGROUP:_root[si]
mov DGROUP:_root[bx], di
mov EGROUP:[di], bx
jmp short min9
$_5: cmp DGROUP:_rson[di], si
jNE $_6
mov DGROUP:_rson[di], bx
jmp short $_7
$_6: mov DGROUP:_lson[di], bx
$_7:
min9: dec word ptr DGROUP:_match_position
cbw
neg ax
add ax, F - 1
mov DGROUP:_match_length, ax
pop di
pop si
ret
_MatchInsertNode endp
;-----------------------------------------------;
public _DeleteNode
_DeleteNode proc near
push si
push di
mov es, DGROUP:extra
mov dx, NIL * 2
shl si, 1
cmp word ptr DGROUP:_dad[si], dx
jNE $_8
jmp dn9
$_8:
cmp word ptr DGROUP:_rson[si], dx
jNE $_10
mov di, DGROUP:_lson[si]
jmp short $_9
$_10:
cmp word ptr DGROUP:_lson[si], dx
jNE $_11
mov di, DGROUP:_rson[si]
jmp short $_9
$_11: mov di, DGROUP:_lson[si]
mov ax, DGROUP:_rson[di]
cmp ax, dx
jE $_13
$_14: mov di, ax
mov ax, DGROUP:_rson[di]
cmp ax, dx
jNE $_14
$_15: mov ax, DGROUP:_lson[di]
mov bx, DGROUP:_dad[di]
mov cx, bx
mov DGROUP:_rson[bx], ax
mov bx, DGROUP:_lson[di]
mov DGROUP:_dad[bx], cx
mov ax, DGROUP:_lson[si]
mov DGROUP:_lson[di], ax
mov bx, DGROUP:_lson[si]
mov DGROUP:_dad[bx], di
$_13: mov ax, DGROUP:_rson[si]
mov DGROUP:_rson[di], ax
mov bx, DGROUP:_rson[si]
mov DGROUP:_dad[bx], di
$_12:
$_9: mov bx, DGROUP:_dad[si]
mov DGROUP:_dad[di], bx
or bx, bx
jNS $_16
mov bx, DGROUP:_root[si]
mov DGROUP:_root[di], bx
mov EGROUP:[bx], di
jmp short $_17
$_16: cmp DGROUP:_rson[bx], si
jNE $_18
mov DGROUP:_rson[bx], di
jmp short $_19
$_18: mov DGROUP:_lson[bx], di
$_19:
$_17: mov DGROUP:_dad[si], dx
dn9: pop di
pop si
ret
_DeleteNode endp
extrn _textsize :word
extrn _infile :word
extrn _StartModel :near
extrn _EncodeChar :near
extrn _EncodePosition :near
extrn _EncodeEnd :near
extrn _outfile :word
extrn _DecodeChar :near
extrn _DecodePosition :near
extrn _blkcnt :word
extrn _curcnt :word
extrn _nxtcnt :word
;-----------------------------------------------;
; LArc type 5 buffer
;-----------------------------------------------;
public InitBuf
InitBuf proc near
cld
mov di, ds
mov es, di
mov di, offset DGROUP:_text_buf
mov al, 0
mov bx, 13
$_20: mov cx, bx
rep stosb
inc al
jNZ $_20
$_21:
$_22: stosb
inc al
jNZ $_22
$_23:
$_24: dec al
stosb
jNZ $_24
$_25: mov cx, 128
rep stosb
mov cx, 128
mov al, 20h
rep stosb
ret
InitBuf endp
;-----------------------------------------------;
; LZHUF encode
;-----------------------------------------------;
public _Encode
_Encode proc near
push si
push di
push bp
mov ax,word ptr DGROUP:_textsize
or ax,word ptr DGROUP:_textsize + 2;
jNZ $_26
jmp en05
$_26: call near ptr _StartModel
call near ptr _InitTree
call near ptr InitBuf
mov cx, F
sub di, cx
en01: mov bx, DGROUP:_infile
getc_crc@
or ax, ax
js en02
stosb
loop en01
en02:
mov ax, F
sub ax, cx
mov word ptr len, ax
xor ax, ax
mov word ptr DGROUP:_textsize, ax
mov word ptr DGROUP:_textsize + 2, ax
mov di, N - F
mov si, di
mov cx, F
$_27: dec di
push cx
call _InsertNode
pop cx
LOOP $_27
$_28: mov di, si
call near ptr _MatchInsertNode
xor si, si
$_29: mov bx, word ptr DGROUP:_match_length
cmp bx, word ptr len
jLE $_31
mov bx, word ptr len;
mov word ptr DGROUP:_match_length, bx
$_31: push si
push di
cmp bx, THRESHOLD
jG $_32
mov word ptr DGROUP:_match_length, 1
mov bl, byte ptr DGROUP:_text_buf[di]
mov bh, 0
call near ptr _EncodeChar
jmp short $_33
$_32: add bx, 255 - THRESHOLD
call near ptr _EncodeChar
mov bx, DGROUP:_match_position
call near ptr _EncodePosition
$_33: pop di
pop si
mov ax, word ptr DGROUP:_match_length
add word ptr DGROUP:_textsize, ax
adc word ptr DGROUP:_textsize + 2, 0
jmp short en03
$_34: call near ptr _InsertNode
en03: call near ptr _DeleteNode
mov bx, DGROUP:_infile
getc_crc@
or ax, ax
jS $_36
mov byte ptr DGROUP:_text_buf[si], al
cmp si, F - 1
jAE $_37
mov DGROUP:_text_buf[si + N], al
$_37: jmp short $_38
$_36: dec word ptr len
$_38: inc si
inc di
and si, N - 1
and di, N - 1
dec _match_length
jNZ $_34
$_35: call near ptr _MatchInsertNode
cmp len, 0
jLE $_39
jmp $_29
$_30:
$_39: call near ptr _EncodeEnd
mov es, DGROUP:extra
mov ah, 49h ; release memory
int 21h
en05:
pop bp
pop di
pop si
ret
_Encode endp
;-----------------------------------------------;
; LZHUF decode
;-----------------------------------------------;
public _Decode
_Decode proc near
push si
push di
push bp
mov ax, word ptr DGROUP:_textsize
or ax, word ptr DGROUP:_textsize+2
jNZ $_40
jmp de9
$_40: call near ptr _StartModel
call near ptr InitBuf
mov di, N - F
$_41: push di
call near ptr _DecodeChar
mov di, ax
cmp ax, 256
jGE $_43
pop di
mov bx, word ptr DGROUP:_outfile
putc_crc@
mov byte ptr DGROUP:_text_buf[di], al
inc di
and di, N - 1
sub DGROUP:_textsize, 1
sbb DGROUP:_textsize + 2, 0
jmp short $_44
$_43: call near ptr _DecodePosition
mov cx, di
pop di
mov si, di
sub si, ax
dec si
and si, N - 1
sub cx, 255 - THRESHOLD
sub DGROUP:_textsize, cx
sbb DGROUP:_textsize + 2, 0
mov dx, DGROUP:_outfile
$_45: mov al, DGROUP:_text_buf[si]
mov DGROUP:_text_buf[di], al
inc si
inc di
and si, N - 1
and di, N - 1
mov bx, dx
putc_crc@
LOOP $_45
$_46:
$_44: mov ax, word ptr DGROUP:_textsize+2
or ax, ax
jS $_47
or ax, word ptr DGROUP:_textsize
jZ $_47
jmp $_41
$_42:
$_47:
de9: call crcend
pop bp
pop di
pop si
ret
_Decode endp
;-----------------------------------------------;
; LArc type 5 decode
;-----------------------------------------------;
public _DecodeOld
_DecodeOld proc near
push si
push di
push bp
push ds
pop es
mov ax, word ptr DGROUP:_textsize
or ax, word ptr DGROUP:_textsize+2
jNZ $_48
jmp do9
$_48:
call near ptr InitBuf
mov di, N - F_OLD
mov dl, 80h
$_49: rol dl, 1
jNC $_51
mov bx, word ptr DGROUP:_infile
getc@
mov dh, al
$_51: mov bx, word ptr DGROUP:_infile
getc@
test dh, dl
jZ $_52
mov bx, word ptr DGROUP:_outfile
putc_crc@
mov byte ptr DGROUP:_text_buf[di], al
inc di
and di, N - 1
sub DGROUP:_textsize, 1
sbb DGROUP:_textsize + 2, 0
jmp short $_53
$_52: mov cl, al
mov bx, word ptr DGROUP:_infile
getc@
mov ch, al
shr ch, 1
shr ch, 1
shr ch, 1
shr ch, 1
mov si, cx
and ax, 000fh
add ax, 3
mov cx, ax
sub DGROUP:_textsize, cx
sbb DGROUP:_textsize + 2, 0
$_54: mov al, DGROUP:_text_buf[si]
mov DGROUP:_text_buf[di], al
mov bx, DGROUP:_outfile
putc_crc@
inc si
inc di
and si, N - 1
and di, N - 1
LOOP $_54
$_55:
$_53: mov ax, word ptr DGROUP:_textsize+2
or ax, ax
jS $_56
or ax, word ptr DGROUP:_textsize
jZ $_56
jmp $_49
$_50:
$_56:
do9: call crcend
pop bp
pop di
pop si
ret
_DecodeOld endp
;-----------------------------------------------;
; sub-module for
; calculate CRC in buffer
;-----------------------------------------------;
; ax = _crc
; cx = length
; si = buffer
;-----------------------------------------------;
MAXBLK equ 64
public crcsub
crcsub proc near
jcxz crcsub9
mov ax, DGROUP:_curcnt
inc DGROUP:_curcnt
cmp ax, DGROUP:_nxtcnt
jB $_57
push bx
push dx
push cx
push ax
mov ah, 40h ; output char to stderr
mov bx, 2
mov cx, 1
mov dx, offset DGROUP:mark
int 21h
pop ax
pop cx
cmp DGROUP:_blkcnt, MAXBLK
jBE $_58
mov bx, MAXBLK ; calculation of next blk
mul bx
mov bx, DGROUP:_blkcnt
dec bx
add ax, bx
adc dx, 0
inc bx
div bx
inc ax
mul bx
mov bx, MAXBLK
div bx
jmp short $_59
$_58: inc ax
$_59: mov DGROUP:_nxtcnt, ax
pop dx
pop bx
$_57: mov ax, DGROUP:_crc
push bx
$_60: xor al, [si]
inc si
mov bl, al ; crc & 0xff
xor bh, bh
mov al, ah ; crc >> 8
xor ah, ah
shl bx, 1
xor ax, crctbl[bx]
LOOP $_60
$_61: pop bx
mov DGROUP:_crc, ax
crcsub9:
ret
crcsub endp
;-----------------------------------------------;
; get CRC for putc in buffer
;-----------------------------------------------;
public crcbuf
crcbuf proc near
push cx
push si
mov cx, 10[bx]
mov si, 8[bx]
sub cx, si
mov bl, 4[bx]
call crcsub
pop si
pop cx
ret
crcbuf endp
;-----------------------------------------------;
; end process of CRC for putc
;-----------------------------------------------;
public crcend
crcend proc near
mov bx, DGROUP:_outfile
test word ptr 2[bx], 0200h
jZ $_62
cmp byte ptr 4[bx], 01h
jE $_63
$_62: call crcbuf
$_63: ret
crcend endp
;-----------------------------------------------;
; CRC & putc
;-----------------------------------------------;
public crcputc
crcputc proc near
push bx
push ax
test word ptr 2[bx], 0200h
jZ $_64
cmp byte ptr 4[bx], 01h
jE $_65
$_64: call crcbuf
jmp short $_66
$_65: xor al, byte ptr DGROUP:_crc;
mov bl, al
xor bh, bh
shl bx, 1
mov ax, crctbl[bx]
xor al, byte ptr DGROUP:_crc + 1
mov DGROUP:_crc, ax
$_66: pop ax
pop bx
cmp DGROUP:_tstflg, 0
jE $_67
push cx
push bx
mov cx, 6[bx]
neg cx
mov [bx], cx
mov cx, 8[bx]
inc cx
mov 10[bx], cx
mov bx, cx
mov [bx - 1], al
pop bx
pop cx
ret
$_67: public fputc
fputc proc near
push dx
push cx
push bx
push ax
call __fputc
inc sp
inc sp
pop bx
or ax, ax
jNS $_68
push DGROUP:_outfname
mov ax, 14 ; WTERR
push ax
call near ptr _error
$_68: pop cx
pop dx
ret
fputc endp
crcputc endp
;-----------------------------------------------;
; CRC & getc
;-----------------------------------------------;
public crcgetc
crcgetc proc near
push dx
push cx
push bx
call __fgetc
pop bx
or ax, ax
jS $_69
push si
push ax
mov si, 8[bx]
mov cx, [bx]
inc cx
call crcsub
pop ax
pop si
$_69: pop cx
pop dx
ret
crcgetc endp
;-----------------------------------------------;
; make CRC table
;-----------------------------------------------;
public _mkcrc
_mkcrc proc near
mov bx, offset DGROUP:crctbl
xor dx, dx
$_70: mov ax, dx
mov cx, 8
$_72: shr ax, 1
jNC $_74
xor ax, 0a001h
$_74: LOOP $_72
$_73: mov [bx], ax
inc bx
inc bx
inc dl
jNZ $_70
$_71: ret
_mkcrc endp
;-----------------------------------------------;
; get CRC for _copyfile
;-----------------------------------------------;
public _getcrc
_getcrc proc near
push si
push cx
mov si, offset DGROUP:_buf2
call crcsub
pop cx
pop si
ret
_getcrc endp
;-----------------------------------------------;
; void copyfile(FILE *f0, FILE *f1, long size)
;-----------------------------------------------;
public _copyfile
_copyfile proc near
__f0 = 4
__f1 = 6
__size = 8
push bp
mov bp, sp
mov DGROUP:_crc, 0
mov ax, __size[bp]
or ax, __size + 2[bp]
jNZ $_75
jmp cf9
$_75: push si
push di
mov si, __f0[bp]
mov di, __f1[bp]
push si
call _ftell
pop cx
mov cx, dx
mov dx, ax
mov bl, 4[si]
xor bh, bh
mov si, bx ; fd0
mov ax, 4200h
int 21h ; lseek
push di
call _ftell
pop cx
mov cx, dx
mov dx, ax
mov bl, 4[di]
xor bh, bh
mov di, bx ; fd1
mov ax, 4200h
int 21h ; lseek
mov dx, offset DGROUP:_buf2
$_76: mov cx, 0a000h
cmp DGROUP:_crcflg, 0
jE $_78
mov cx, 01000h
$_78: cmp word ptr __size + 2[bp], 0
jNZ $_79
cmp cx, __size[bp]
jBE $_79
mov cx, __size[bp]
$_79: mov bx, si
mov ah, 3fh
int 21h
jC $_80
cmp ax, cx
jE $_81
$_80: push DGROUP:_infname
mov ax, 13 ; RDERR
push ax
call _error
$_81: cmp DGROUP:_tstflg, 0
jNE $_82
mov bx, di
mov ah, 40h
int 21h
jC $_83
dec bx ; STDOUT ?
jne cf1
mov ax, cx
cf1: inc bx
cmp ax, cx
jE $_84
$_83: push DGROUP:_outfname
mov ax, 14 ; WTERR
push ax
call _error
$_84:
$_82: sub __size[bp], ax
sbb word ptr __size + 2[bp], 0
cmp DGROUP:_crcflg, 0
jE $_85
call _getcrc
$_85: mov ax, __size[bp]
or ax, __size + 2[bp]
jNZ $_76
$_77: xor cx, cx
mov bx, di
mov ah, 40h ; to abandon rest of old file
int 21h
push cx
mov dx, cx
mov bx, si
mov ax, 4201h ; lseek
int 21h
push dx
push ax
push word ptr __f0[bp]
call near ptr _fseek
add sp, 8
xor cx, cx
push cx
mov dx, cx
mov bx, di
mov ax, 4201h ; lseek
int 21h
push dx
push ax
push word ptr __f1[bp]
call near ptr _fseek
add sp, 8
pop di
pop si
cf9:
pop bp
ret
_copyfile endp
_TEXT ends
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/