Metropoli BBS
VIEWER: sd.asm MODE: TEXT (CP437)
;─────────────────────────────────────────────────────────────────────Decode────
N       = 4096                  ; size of ring buffer
F	= 18			; upper limit for match_length
THRESHOLD = 2			; encode string into position and length
				; if match_length is greater than this

flags	dw	0
textbuf dw	0

; bx - Handle
; cx - Num Bytes Long
; es:di - output
textsize	dd	0
codesize	dd	0

proc		GetDecodeSizes
		push	ds bx
		mov	ax,cs
                mov     ds,ax
                mov     ah,3Fh
		mov	cx,8
		mov	dx,offset textsize
		int	21h
		mov	si,[Word cs:textsize+2]
		mov	di,[Word cs:textsize]
		mov	dx,[Word cs:codesize+2]
		mov	cx,[Word cs:codesize]
		pop	bx ds
		ret
endp            GetDecodeSizes

proc		Decode
		push	ds
		mov	dx,[cs:TopOfData]
		mov	[cs:textbuf],dx
		add	dx,(N+F-1)/4+1

		mov	ds,dx		; Load buffer
		mov	dx,0
		mov	ah,3Fh
		int	21h
		mov	si,0

		push	cx es
;               for (i = 0;i < N - F;i++) text_buf[i] = ' ';
		mov	di,0
		mov	ax,[cs:textbuf]
		mov	es,ax
		mov	cx,N-F
		mov	al,' '
		rep	stosb
		pop	es cx
		mov	di,0

;		r = N - F; flags = 0;
                mov     [Word cs:flags],0
;		 mov	 [Word cs:r],N-F
		mov	bx,N-F		; R
;  for (;;)
;  {
;		if (((flags >>= 1) & 256) == 0)
@@DecodeLoop:   shr     [Word cs:flags],1
		mov	ax,[Word cs:flags]
		and	ax,256
		jnz	@@NextFlagCheck

;		{
;		  if ((c = getc(in)) == EOF) break;
		lodsb
		cmp	si,cx
		jnb	@@Finish
;		  flags = c | 0xff00;	 /* uses higher byte cleverly to count eight */
                or      ah,0ffh
		mov	[Word cs:flags],ax
;		}
;		if (flags & 1)
@@NextFlagCheck:mov	ax,[cs:flags]
		and	ax,1
		jz	@@FlagCh2
;		{
;		  if ((c = getc(in)) == EOF) break;
		lodsb
		cmp	si,cx
		jg	@@Finish
;		  putc(c, out); text_buf[r++] = c; r &= (N - 1);
                stosb
		push	es
		mov	es,[cs:textbuf]
		mov	[es:bx],al
		inc	bx
		pop	es
		and	bx,N-1
		jmp	@@DecodeLoop
;		}
;		else
;		{
;		  if ((i = getc(in)) == EOF) break;
@@FlagCh2:	xor	ah,ah
		lodsb
		cmp	si,cx
		jg	@@Finish
                mov     dx,ax                           ; i = DX
;		  if ((j = getc(in)) == EOF) break;
		lodsb					; j = AX
		cmp	si,cx
		jg	@@Finish
;                 i |= ((j & 0xf0) << 4);
		push	ax
		and	ax,0f0h
		shl	ax,4
		or	dx,ax
		pop	ax
;		  j = (j & 0x0f) + THRESHOLD;
		and	ax,0fh
		add	ax,THRESHOLD
;		  for (k = 0;k <= j;k++)
		mov	bp,0			; k
@@kloop:
		push	ax			; Save j
;                 {
;		  c = text_buf[(i + k) & (N - 1)];
		push	es bx
		mov	es,[cs:textbuf]
		mov	bx,dx			; i
		add	bx,bp			; +k
		and	bx,N-1
		mov	al,[es:bx]
		pop	bx es
;		  putc(c, out);
                stosb
;		  text_buf[r++] = c; r &= (N - 1);
		push	es
		mov	es,[cs:textbuf]
		mov	[es:bx],al
		inc	bx
		pop	es
                and     bx,N-1
		inc	bp			; k++
		pop	ax
		cmp	bp,ax			; k<=j
		jle	@@kloop
		jmp	@@DecodeLoop
@@Finish:	pop	ds
		ret
endp            Decode

;─────────────────────────────────────────────────────────────────────Decode────
SoundFile:	db	'MUSIC210.INF',0,0,0
; CX:DX - Sound Driver Filename
SoundHandle     dw      0
proc		LoadSoundDriver
		push	ds
		push	ds
		mov	ds,cx
		mov	ax,3D00h
		int	21h
		jb	@@NoFind
		pop	ds
		mov	[cs:SoundHandle],ax
		mov	bx,ax
		call	GetDecodeSizes
		mov	bx,di
		shr	bx,4
		inc	bx
		mov	ax,[cs:TopOfData]
		mov	[Word cs:Music+2],ax
		add	[cs:TopOfData],bx
		mov	es,ax
		mov	di,0
		mov	bx,[cs:SoundHandle]
		call	Decode
		mov	bx,[cs:SoundHandle]
		mov	ah,3Eh
		int	21h
		pop	ds
		clc
		ret
@@NoFind:	pop	ax ax
		stc
		ret
endp            LoadSoundDriver

[ RETURN TO DIRECTORY ]