1153 lines
27 KiB
NASM
1153 lines
27 KiB
NASM
![]() |
;
|
||
|
; Command & Conquer Red Alert(tm)
|
||
|
; Copyright 2025 Electronic Arts Inc.
|
||
|
;
|
||
|
; This program is free software: you can redistribute it and/or modify
|
||
|
; it under the terms of the GNU General Public License as published by
|
||
|
; the Free Software Foundation, either version 3 of the License, or
|
||
|
; (at your option) any later version.
|
||
|
;
|
||
|
; This program is distributed in the hope that it will be useful,
|
||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
; GNU General Public License for more details.
|
||
|
;
|
||
|
; You should have received a copy of the GNU General Public License
|
||
|
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
;
|
||
|
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
|
||
|
;*
|
||
|
;*---------------------------------------------------------------------------
|
||
|
;*
|
||
|
;* PROJECT
|
||
|
;* VQAPlay library.
|
||
|
;*
|
||
|
;* FILE
|
||
|
;* UnVQBuff.asm
|
||
|
;*
|
||
|
;* DESCRIPTION
|
||
|
;* Buffered VQ decompress/draw routines.
|
||
|
;*
|
||
|
;* PROGRAMMER
|
||
|
;* Denzil E. Long, Jr.
|
||
|
;*
|
||
|
;* DATE
|
||
|
;* Feburary 8, 1995
|
||
|
;*
|
||
|
;*---------------------------------------------------------------------------
|
||
|
;*
|
||
|
;* PUBLIC
|
||
|
;* UnVQ_2x2 - Draw 2x2 block VQ frame to a buffer.
|
||
|
;* UnVQ_2x3 - Draw 2x3 block VQ frame to a buffer.
|
||
|
;* UnVQ_4x2 - Draw 4x2 block VQ frame to a buffer.
|
||
|
;* UnVQ_4x4 - Draw 4x4 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
IDEAL
|
||
|
P386
|
||
|
MODEL USE32 FLAT
|
||
|
LOCALS ??
|
||
|
INCLUDE "vga.i"
|
||
|
INCLUDE "vesavid.i"
|
||
|
INCLUDE "vqaplay.i"
|
||
|
CODESEG
|
||
|
|
||
|
SKIP_PTR EQU 8000h
|
||
|
|
||
|
|
||
|
IF VQABLOCK_2X2
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_2x2 - Draw 2x2 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_2x2(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
;*
|
||
|
;* void UnVQ_2x2(unsigned char *, unsigned char *, unsigned char *,
|
||
|
;* unsigned short, unsigned short, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image into the specified buffer from the
|
||
|
;* pointers and codebook provided. This routine has been optimized for
|
||
|
;* a 320x200 image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* BufWidth - Width of destination buffer in pixels.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
GLOBAL C UnVQ_2x2:NEAR
|
||
|
PROC UnVQ_2x2 C NEAR USES ebx ecx edx esi edi
|
||
|
|
||
|
ARG codebook:NEAR PTR
|
||
|
ARG pointers:NEAR PTR
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
ARG buffer:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
ARG buffer:NEAR PTR
|
||
|
ENDIF
|
||
|
|
||
|
ARG blocksperrow:DWORD
|
||
|
ARG numrows:DWORD
|
||
|
ARG bufwidth:DWORD
|
||
|
|
||
|
LOCAL data_end:DWORD
|
||
|
LOCAL cb_offset:DWORD
|
||
|
LOCAL edi_startval:DWORD
|
||
|
LOCAL rowoffset:DWORD
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Initialize
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
mov eax,[codebook] ;Adjust the codebook address so
|
||
|
sub eax,4 ; that the pointer offsets will
|
||
|
mov [cb_offset],eax ; point directly at the codeword.
|
||
|
|
||
|
mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
shl eax,1 ; row of blocks.
|
||
|
mov [rowoffset],eax
|
||
|
|
||
|
mov esi,[pointers]
|
||
|
mov eax,[numrows] ;Compute the end address of the
|
||
|
mul [blocksperrow] ; pointer data.
|
||
|
shl eax,1
|
||
|
add eax,esi
|
||
|
mov [data_end],eax
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
push es
|
||
|
les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
mov edi,[buffer]
|
||
|
ENDIF
|
||
|
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Drawing loop
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
??Start_row:
|
||
|
mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
|
||
|
??Not_finished_a_line:
|
||
|
sub ebx,ebx
|
||
|
mov bx,[WORD PTR esi] ;Get the codebook pointer value
|
||
|
add esi,2 ; then advance to the next one.
|
||
|
|
||
|
or bx,bx ;Is it a one color block?
|
||
|
js short ??One_color
|
||
|
|
||
|
; Draw multi-color block
|
||
|
|
||
|
add ebx,[cb_offset] ;Codeword address
|
||
|
mov eax,[ebx] ;Read codeword
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],ax ;Write 1st row to dest
|
||
|
ELSE
|
||
|
mov [edi],ax ;Write 1st row to dest
|
||
|
ENDIF
|
||
|
|
||
|
shr eax,16
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],ax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],ax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
|
||
|
add edi,2 ;Next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
; Draw 1-color block
|
||
|
|
||
|
??One_color:
|
||
|
cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
jne ??Draw_One_Color
|
||
|
|
||
|
add edi,2 ;Move to next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
jmp ??Next_row
|
||
|
|
||
|
??Draw_One_Color:
|
||
|
not bx ;NOT pointer value to get color
|
||
|
mov bh,bl ;Duplicate color through the
|
||
|
mov ax,bx ; entire dword register.
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],ax ;Write 1st row to dest
|
||
|
mov [es:edi+ebx],ax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi],ax ;Write 1st row to dest
|
||
|
mov [edi+ebx],ax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add edi,2 ;Next dest block positionw
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
??Next_row:
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
IF PHARLAP_TNT
|
||
|
pop es
|
||
|
ENDIF
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_2x2
|
||
|
ENDIF ;VQABLOCK_2X2
|
||
|
|
||
|
|
||
|
IF VQABLOCK_2X3
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_2x3 - Draw 2x3 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_2x3(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
;*
|
||
|
;* void UnVQ_2x3(unsigned char *, unsigned char *, unsigned char *,
|
||
|
;* unsigned short, unsigned short, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image into the specified buffer from the
|
||
|
;* pointers and codebook provided. This routine has been optimized for
|
||
|
;* a 320x200 image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* BufWidth - Width of destination buffer in pixels.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
GLOBAL C UnVQ_2x3:NEAR
|
||
|
PROC UnVQ_2x3 C NEAR USES ebx ecx edx esi edi
|
||
|
|
||
|
ARG codebook:NEAR PTR
|
||
|
ARG pointers:NEAR PTR
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
ARG buffer:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
ARG buffer:NEAR PTR
|
||
|
ENDIF
|
||
|
|
||
|
ARG blocksperrow:DWORD
|
||
|
ARG numrows:DWORD
|
||
|
ARG bufwidth:DWORD
|
||
|
|
||
|
LOCAL data_end:DWORD
|
||
|
LOCAL cb_offset:DWORD
|
||
|
LOCAL edi_startval:DWORD
|
||
|
LOCAL rowoffset:DWORD
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Initialize
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
mov eax,[codebook] ;Adjust the codebook address so
|
||
|
sub eax,4 ; that the pointer offsets will
|
||
|
mov [cb_offset],eax ; point directly at the codeword.
|
||
|
|
||
|
mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
shl eax,1 ; row of blocks.
|
||
|
add eax,[bufwidth]
|
||
|
mov [rowoffset],eax
|
||
|
|
||
|
mov esi,[pointers]
|
||
|
mov eax,[numrows] ;Compute the end address of the
|
||
|
mul [blocksperrow] ; pointer data.
|
||
|
shl eax,1
|
||
|
add eax,esi
|
||
|
mov [data_end],eax
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
push es
|
||
|
les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
mov edi,[buffer]
|
||
|
ENDIF
|
||
|
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Drawing loop
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
??Start_row:
|
||
|
mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
|
||
|
??Not_finished_a_line:
|
||
|
sub ebx,ebx
|
||
|
mov bx,[WORD PTR esi] ;Get the codebook pointer value
|
||
|
add esi,2 ; then advance to the next one.
|
||
|
|
||
|
or bx,bx ;Is it a one color block?
|
||
|
js short ??One_color
|
||
|
|
||
|
; Draw multi-color block
|
||
|
|
||
|
add ebx,[cb_offset] ;Codeword address
|
||
|
mov eax,[ebx] ;Read 1st row of codeword
|
||
|
mov dx,[ebx+4] ;Read 2nd row of codeword
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],ax ;Write 1st row to dest
|
||
|
ELSE
|
||
|
mov [edi],ax ;Write 1st row to dest
|
||
|
ENDIF
|
||
|
|
||
|
shr eax,16
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],ax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],ax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],dx
|
||
|
ELSE
|
||
|
mov [edi+ebx],dx
|
||
|
ENDIF
|
||
|
|
||
|
add edi,2 ;Next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
; Draw 1-color block
|
||
|
|
||
|
??One_color:
|
||
|
cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
jne ??Draw_One_Color
|
||
|
|
||
|
add edi,2 ;Move to next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
jmp ??Next_row
|
||
|
|
||
|
??Draw_One_Color:
|
||
|
not bx ;NOT pointer value to get color
|
||
|
mov bh,bl ;Duplicate color through the
|
||
|
mov ax,bx ; entire dword register.
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],ax ;Write 1st row to dest
|
||
|
mov [es:edi+ebx],ax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi],ax ;Write 1st row to dest
|
||
|
mov [edi+ebx],ax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],ax ;Write 2rd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],ax ;Write 2rd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add edi,2 ;Next dest block positionw
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
??Next_row:
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
IF PHARLAP_TNT
|
||
|
pop es
|
||
|
ENDIF
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_2x3
|
||
|
ENDIF ;VQABLOCK_2X3
|
||
|
|
||
|
|
||
|
IF VQABLOCK_4X2
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_4x2 - Draw 4x2 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_4x2(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
;*
|
||
|
;* void UnVQ_4x2(unsigned char *, unsigned char *, unsigned char *,
|
||
|
;* long, long, long);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image into the specified buffer from the
|
||
|
;* pointers and codebook provided. This routine has been optimized for
|
||
|
;* a 320x200 image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* BufWidth - Width of destination buffer in pixels.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
;;; GLOBAL C UnVQ_4x2:NEAR
|
||
|
;;; PROC UnVQ_4x2 C NEAR USES ebx ecx edx esi edi
|
||
|
;;;
|
||
|
;;; ARG codebook:NEAR PTR
|
||
|
;;; ARG pointers:NEAR PTR
|
||
|
;;;
|
||
|
;;; IF PHARLAP_TNT
|
||
|
;;; ARG buffer:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||
|
;;; ELSE
|
||
|
;;; ARG buffer:NEAR PTR
|
||
|
;;; ENDIF
|
||
|
;;;
|
||
|
;;; ARG blocksperrow:DWORD
|
||
|
;;; ARG numrows:DWORD
|
||
|
;;; ARG bufwidth:DWORD
|
||
|
;;;
|
||
|
;;; LOCAL data_end:DWORD
|
||
|
;;; LOCAL cb_offset:DWORD
|
||
|
;;; LOCAL edi_startval:DWORD
|
||
|
;;; LOCAL rowoffset:DWORD
|
||
|
;;;
|
||
|
;;;;----------------------------------------------------------------------------
|
||
|
;;;; Initialize
|
||
|
;;;;----------------------------------------------------------------------------
|
||
|
;;;
|
||
|
;;; mov eax,[codebook] ;Adjust the codebook address so
|
||
|
;;; sub eax,4 ; that the pointer offsets will
|
||
|
;;; mov [cb_offset],eax ; point directly at the codeword.
|
||
|
;;;
|
||
|
;;; mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
;;; shl eax,1 ; row of blocks.
|
||
|
;;; mov [rowoffset],eax
|
||
|
;;;
|
||
|
;;; mov esi,[pointers]
|
||
|
;;; mov eax,[numrows] ;Compute the end address of the
|
||
|
;;; mul [blocksperrow] ; pointer data.
|
||
|
;;; shl eax,1
|
||
|
;;; add eax,esi
|
||
|
;;; mov [data_end],eax
|
||
|
;;;
|
||
|
;;; IF PHARLAP_TNT
|
||
|
;;; push es
|
||
|
;;; les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
|
||
|
;;; ELSE
|
||
|
;;; mov edi,[buffer]
|
||
|
;;; ENDIF
|
||
|
;;;
|
||
|
;;; mov [edi_startval],edi
|
||
|
;;;
|
||
|
;;;;----------------------------------------------------------------------------
|
||
|
;;;; Drawing loop
|
||
|
;;;;----------------------------------------------------------------------------
|
||
|
;;;
|
||
|
;;;??Start_row:
|
||
|
;;; mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
;;;
|
||
|
;;;??Not_finished_a_line:
|
||
|
;;; sub ebx,ebx
|
||
|
;;; mov bx,[WORD PTR esi] ;Get the codebook pointer value
|
||
|
;;; add esi,2 ; then advance to the next one.
|
||
|
;;;
|
||
|
;;; or bx,bx ;Is it a one color block?
|
||
|
;;; js short ??One_color
|
||
|
;;;
|
||
|
;;;; Draw multi-color block
|
||
|
;;;
|
||
|
;;; add ebx,[cb_offset] ;Codeword address
|
||
|
;;; mov eax,[ebx] ;Read 1st row of codeword
|
||
|
;;; mov edx,[ebx+4] ;Read 2nd row of codeword
|
||
|
;;; mov ebx,[bufwidth]
|
||
|
;;;
|
||
|
;;; IF PHARLAP_TNT
|
||
|
;;; mov [es:edi],eax ;Write 1st row to dest
|
||
|
;;; mov [es:edi+ebx],edx ;Write 2nd row to dest
|
||
|
;;; ELSE
|
||
|
;;; mov [edi],eax ;Write 1st row to dest
|
||
|
;;; mov [edi+ebx],edx ;Write 2nd row to dest
|
||
|
;;; ENDIF
|
||
|
;;;
|
||
|
;;; add edi,4 ;Next dest block position
|
||
|
;;; dec ecx ;More blocks for this row?
|
||
|
;;; jnz short ??Not_finished_a_line
|
||
|
;;;
|
||
|
;;;; Advance to the next destination row of blocks.
|
||
|
;;;
|
||
|
;;; mov edi,[edi_startval]
|
||
|
;;; add edi,[rowoffset]
|
||
|
;;; mov [edi_startval],edi
|
||
|
;;;
|
||
|
;;; cmp esi,[data_end] ;Have we reached the end of the
|
||
|
;;; jnb short ??End_of_data ; pointers buffer?
|
||
|
;;; jmp ??Start_row
|
||
|
;;;
|
||
|
;;;; Draw 1-color block
|
||
|
;;;
|
||
|
;;;??One_color:
|
||
|
;;; cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
;;; jne ??Draw_One_Color
|
||
|
;;;
|
||
|
;;; add edi,4 ;Move to next dest block position
|
||
|
;;; dec ecx ;More blocks for this row?
|
||
|
;;; jnz short ??Not_finished_a_line
|
||
|
;;; jmp ??Next_row
|
||
|
;;;
|
||
|
;;;??Draw_One_Color:
|
||
|
;;; not bx ;NOT pointer value to get color
|
||
|
;;; mov bh,bl ;Duplicate color through the
|
||
|
;;; mov ax,bx ; entire dword register.
|
||
|
;;; rol eax,16
|
||
|
;;; mov ax,bx
|
||
|
;;; mov ebx,[bufwidth]
|
||
|
;;;
|
||
|
;;; IF PHARLAP_TNT
|
||
|
;;; mov [es:edi],eax ;Write 1st row to dest
|
||
|
;;; mov [es:edi+ebx],eax ;Write 2nd row to dest
|
||
|
;;; ELSE
|
||
|
;;; mov [edi],eax ;Write 1st row to dest
|
||
|
;;; mov [edi+ebx],eax ;Write 2nd row to dest
|
||
|
;;; ENDIF
|
||
|
;;;
|
||
|
;;; add edi,4 ;Next dest block positionw
|
||
|
;;; dec ecx ;More blocks for this row?
|
||
|
;;; jnz short ??Not_finished_a_line
|
||
|
;;;
|
||
|
;;;; Advance to the next destination row of blocks.
|
||
|
;;;
|
||
|
;;;??Next_row:
|
||
|
;;; mov edi,[edi_startval]
|
||
|
;;; add edi,[rowoffset]
|
||
|
;;; mov [edi_startval],edi
|
||
|
;;;
|
||
|
;;; cmp esi,[data_end] ;Have we reached the end of the
|
||
|
;;; jnb short ??End_of_data ; pointers buffer?
|
||
|
;;; jmp ??Start_row
|
||
|
;;;
|
||
|
;;;??End_of_data:
|
||
|
;;; IF PHARLAP_TNT
|
||
|
;;; pop es
|
||
|
;;; ENDIF
|
||
|
;;;
|
||
|
;;; ret
|
||
|
;;;
|
||
|
;;; ENDP UnVQ_4x2
|
||
|
;;; ENDIF ;VQABLOCK_4X2
|
||
|
|
||
|
GLOBAL C UnVQ_4x2:NEAR
|
||
|
PROC UnVQ_4x2 C NEAR USES ebx ecx edx esi edi
|
||
|
|
||
|
ARG codebook:NEAR PTR
|
||
|
ARG pointers:NEAR PTR
|
||
|
ARG buffer:NEAR PTR
|
||
|
ARG blocksperrow:DWORD
|
||
|
ARG numrows:DWORD
|
||
|
ARG bufwidth:DWORD
|
||
|
|
||
|
LOCAL data_end:DWORD
|
||
|
LOCAL cb_offset:DWORD
|
||
|
LOCAL edi_startval:DWORD
|
||
|
LOCAL rowoffset:DWORD
|
||
|
LOCAL entries:DWORD
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Initialize
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
mov eax,[codebook] ;Adjust the codebook address so
|
||
|
; sub eax,4 ; that the pointer offsets will
|
||
|
mov [cb_offset],eax ; point directly at the codeword.
|
||
|
|
||
|
mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
shl eax,1 ; row of blocks.
|
||
|
mov [rowoffset],eax
|
||
|
|
||
|
mov esi,[pointers]
|
||
|
mov eax,[numrows] ;Compute the end address of the
|
||
|
mul [blocksperrow] ; pointer data.
|
||
|
mov [entries],eax
|
||
|
add eax,esi
|
||
|
mov [data_end],eax
|
||
|
|
||
|
mov edi,[buffer]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Drawing loop
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
??Start_row:
|
||
|
mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
|
||
|
??Not_finished_a_line:
|
||
|
mov eax,[entries]
|
||
|
xor ebx,ebx
|
||
|
mov bl,[esi]
|
||
|
mov bh,[esi + eax] ;Get the codebook pointer value
|
||
|
inc esi ; then advance to the next one.
|
||
|
|
||
|
cmp bh,00Fh ;Is it a one color block?
|
||
|
je short ??One_color
|
||
|
|
||
|
; Draw multi-color block
|
||
|
|
||
|
shl ebx,3
|
||
|
add ebx,[cb_offset] ;Codeword address
|
||
|
mov eax,[ebx] ;Read 1st row of codeword
|
||
|
mov edx,[ebx+4] ;Read 2nd row of codeword
|
||
|
mov ebx,[bufwidth]
|
||
|
mov [edi],eax ;Write 1st row to dest
|
||
|
mov [edi+ebx],edx ;Write 2nd row to dest
|
||
|
|
||
|
add edi,4 ;Next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
; Draw 1-color block
|
||
|
|
||
|
??One_color:
|
||
|
; cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
; jne ??Draw_One_Color
|
||
|
;
|
||
|
; add edi,4 ;Move to next dest block position
|
||
|
; dec ecx ;More blocks for this row?
|
||
|
; jnz short ??Not_finished_a_line
|
||
|
; jmp ??Next_row
|
||
|
|
||
|
??Draw_One_Color:
|
||
|
; not bx ;NOT pointer value to get color
|
||
|
mov bh,bl ;Duplicate color through the
|
||
|
mov ax,bx ; entire dword register.
|
||
|
rol eax,16
|
||
|
mov ax,bx
|
||
|
mov ebx,[bufwidth]
|
||
|
mov [edi],eax ;Write 1st row to dest
|
||
|
mov [edi+ebx],eax ;Write 2nd row to dest
|
||
|
|
||
|
add edi,4 ;Next dest block positionw
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
??Next_row:
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_4x2
|
||
|
ENDIF ;VQABLOCK_4X2
|
||
|
|
||
|
|
||
|
IF VQABLOCK_4X4
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_4x4 - Draw 4x4 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_4x4(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
;*
|
||
|
;* void UnVQ_4x4(unsigned char *, unsigned char *, unsigned char *,
|
||
|
;* unsigned short, unsigned short, unsigned short);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image into the specified buffer from the
|
||
|
;* pointers and codebook provided. This routine has been optimized for
|
||
|
;* a 320x200 image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* BufWidth - Width of destination buffer in pixels.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
GLOBAL C UnVQ_4x4:NEAR
|
||
|
PROC UnVQ_4x4 C NEAR USES ebx ecx edx esi edi
|
||
|
|
||
|
ARG codebook:NEAR PTR
|
||
|
ARG pointers:NEAR PTR
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
ARG buffer:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
ARG buffer:NEAR PTR
|
||
|
ENDIF
|
||
|
|
||
|
ARG blocksperrow:DWORD
|
||
|
ARG numrows:DWORD
|
||
|
ARG bufwidth:DWORD
|
||
|
|
||
|
LOCAL data_end:DWORD
|
||
|
LOCAL cb_offset:DWORD
|
||
|
LOCAL edi_startval:DWORD
|
||
|
LOCAL rowoffset:DWORD
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Initialize
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
mov eax,[codebook] ;Adjust the codebook address so
|
||
|
sub eax,4 ; that the pointer offsets will
|
||
|
mov [cb_offset],eax ; point directly at the codeword.
|
||
|
|
||
|
mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
shl eax,2 ; row of blocks
|
||
|
mov [rowoffset],eax
|
||
|
|
||
|
mov esi,[pointers]
|
||
|
mov eax,[numrows] ;Compute the end address of the
|
||
|
mul [blocksperrow] ; pointer data.
|
||
|
shl eax,1
|
||
|
add eax,esi
|
||
|
mov [data_end],eax
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
push es
|
||
|
les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
mov edi,[buffer]
|
||
|
ENDIF
|
||
|
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Drawing loop
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
??Start_row:
|
||
|
mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
|
||
|
??Not_finished_a_line:
|
||
|
sub ebx,ebx
|
||
|
mov bx,[WORD PTR esi] ;Get the codebook pointer value
|
||
|
add esi,2 ; then advance to the next one.
|
||
|
|
||
|
or bx,bx ;Is it a one color block?
|
||
|
js short ??One_color
|
||
|
|
||
|
; Draw multi-color block
|
||
|
|
||
|
add ebx,[cb_offset] ;Codeword address
|
||
|
mov eax,[ebx] ;Read 1st row of codeword
|
||
|
mov edx,[ebx+4] ;Read 2nd row of codeword
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],eax ;Write 1st row to dest
|
||
|
ELSE
|
||
|
mov [edi],eax ;Write 1st row to dest
|
||
|
ENDIF
|
||
|
|
||
|
mov eax,ebx
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],edx ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],edx ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
mov ebx,eax
|
||
|
mov eax,[ebx+8]
|
||
|
mov edx,[ebx+12]
|
||
|
mov ebx,[bufwidth]
|
||
|
shl ebx,1
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],eax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],eax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],edx ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],edx ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add edi,4 ;Next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
; Draw 1-color block
|
||
|
|
||
|
??One_color:
|
||
|
cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
jne ??Draw_One_Color
|
||
|
|
||
|
add edi,4 ;Move to next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
jmp ??Next_row
|
||
|
|
||
|
??Draw_One_Color:
|
||
|
not bx ;NOT pointer value to get color
|
||
|
mov bh,bl ;Duplicate color through the
|
||
|
mov ax,bx ; entire dword register.
|
||
|
rol eax,16
|
||
|
mov ax,bx
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],eax ;Write 1st row to dest
|
||
|
mov [es:edi+ebx],eax ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi],eax ;Write 1st row to dest
|
||
|
mov [edi+ebx],eax ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],eax ;Write 3rd row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],eax ;Write 3rd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi+ebx],eax ;Write 4th row to dest
|
||
|
ELSE
|
||
|
mov [edi+ebx],eax ;Write 4th row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add edi,4 ;Next dest block positionw
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
??Next_row:
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
IF PHARLAP_TNT
|
||
|
pop es
|
||
|
ENDIF
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_4x4
|
||
|
ENDIF ;VQABLOCK_4X4
|
||
|
|
||
|
|
||
|
IF VQABLOCK_WOOFER
|
||
|
IF VQABLOCK_4X2
|
||
|
;****************************************************************************
|
||
|
;*
|
||
|
;* NAME
|
||
|
;* UnVQ_4x2_Woofer - Draw 4x2 block VQ frame to a buffer.
|
||
|
;*
|
||
|
;* SYNOPSIS
|
||
|
;* UnVQ_4x2_Woofer(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
;*
|
||
|
;* void UnVQ_4x2_Woofer(unsigned char *, unsigned char *,
|
||
|
;* unsigned char *, long, long, long);
|
||
|
;*
|
||
|
;* FUNCTION
|
||
|
;* This function draws an image into the specified buffer from the
|
||
|
;* pointers and codebook provided. This routine has been optimized for
|
||
|
;* a 320x200 image.
|
||
|
;*
|
||
|
;* INPUTS
|
||
|
;* Codebook - Pointer to codebook used to draw image.
|
||
|
;* Pointers - Pointer to vector pointer data.
|
||
|
;* Buffer - Pointer to buffer to draw image into.
|
||
|
;* BPR - Number of blocks per row.
|
||
|
;* Rows - Number of rows.
|
||
|
;* BufWidth - Width of destination buffer in pixels.
|
||
|
;*
|
||
|
;* RESULT
|
||
|
;* NONE
|
||
|
;*
|
||
|
;****************************************************************************
|
||
|
|
||
|
GLOBAL C UnVQ_4x2_Woofer:NEAR
|
||
|
PROC UnVQ_4x2_Woofer C NEAR USES ebx ecx edx esi edi
|
||
|
|
||
|
ARG codebook:NEAR PTR
|
||
|
ARG pointers:NEAR PTR
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
ARG buffer:QWORD ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
ARG buffer:NEAR PTR
|
||
|
ENDIF
|
||
|
|
||
|
ARG blocksperrow:DWORD
|
||
|
ARG numrows:DWORD
|
||
|
ARG bufwidth:DWORD
|
||
|
|
||
|
LOCAL data_end:DWORD
|
||
|
LOCAL cb_offset:DWORD
|
||
|
LOCAL edi_startval:DWORD
|
||
|
LOCAL rowoffset:DWORD
|
||
|
LOCAL entries:DWORD
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Initialize
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
mov eax,[codebook] ;Adjust the codebook address so
|
||
|
; sub eax,4 ; that the pointer offsets will
|
||
|
mov [cb_offset],eax ; point directly at the codeword.
|
||
|
|
||
|
mov eax,[bufwidth] ;Compute the offset to the next
|
||
|
shl eax,1 ; row of blocks.
|
||
|
mov [rowoffset],eax
|
||
|
|
||
|
mov esi,[pointers]
|
||
|
mov eax,[numrows] ;Compute the end address of the
|
||
|
mul [blocksperrow] ; pointer data.
|
||
|
mov [entries],eax
|
||
|
; shl eax,1
|
||
|
add eax,esi
|
||
|
mov [data_end],eax
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
push es
|
||
|
les edi,[FWORD buffer] ;KLUDGE - bcc32 pads FARPTR
|
||
|
ELSE
|
||
|
mov edi,[buffer]
|
||
|
ENDIF
|
||
|
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
;----------------------------------------------------------------------------
|
||
|
; Drawing loop
|
||
|
;----------------------------------------------------------------------------
|
||
|
|
||
|
??Start_row:
|
||
|
mov ecx,[blocksperrow] ;Number of blocks in a line
|
||
|
|
||
|
??Not_finished_a_line:
|
||
|
mov eax,[entries]
|
||
|
xor ebx,ebx
|
||
|
; mov bx,[WORD PTR esi] ;Get the codebook pointer value
|
||
|
; add esi,2 ; then advance to the next one.
|
||
|
mov bl,[esi]
|
||
|
mov bh,[esi + eax]
|
||
|
inc esi
|
||
|
|
||
|
; or bx,bx ;Is it a one color block?
|
||
|
; js short ??One_color
|
||
|
|
||
|
cmp bh,00Fh
|
||
|
je short ??One_color
|
||
|
|
||
|
; Draw multi-color block
|
||
|
|
||
|
shl ebx,3
|
||
|
|
||
|
add ebx,[cb_offset] ;Codeword address
|
||
|
mov eax,[ebx] ;Read 1st row of codeword
|
||
|
mov edx,[ebx+4] ;Read 2nd row of codeword
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],al ;Write 1st row to dest
|
||
|
shr eax,16
|
||
|
mov [es:edi+2],al
|
||
|
mov [es:edi+ebx+1],dh ;Write 1st row to dest
|
||
|
shr edx,16
|
||
|
mov [es:edi+ebx+3],dh
|
||
|
ELSE
|
||
|
mov [edi],al ;Write 1st row to dest
|
||
|
shr eax,16
|
||
|
mov [edi+2],al
|
||
|
mov [edi+ebx+1],dh ;Write 1st row to dest
|
||
|
shr edx,16
|
||
|
mov [edi+ebx+3],dh
|
||
|
ENDIF
|
||
|
|
||
|
add edi,4 ;Next dest block position
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz short ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
; Draw 1-color block
|
||
|
|
||
|
??One_color:
|
||
|
; cmp bx,SKIP_PTR ;Is this a skip block?
|
||
|
; jne ??Draw_One_Color
|
||
|
|
||
|
; add edi,4 ;Move to next dest block position
|
||
|
; dec ecx ;More blocks for this row?
|
||
|
; jnz short ??Not_finished_a_line
|
||
|
; jmp ??Next_row
|
||
|
|
||
|
??Draw_One_Color:
|
||
|
; not bx ;NOT pointer value to get color
|
||
|
mov al,bl
|
||
|
mov ebx,[bufwidth]
|
||
|
|
||
|
IF PHARLAP_TNT
|
||
|
mov [es:edi],al
|
||
|
mov [es:edi+2],al
|
||
|
mov [es:edi+ebx+1],al ;Write 2nd row to dest
|
||
|
mov [es:edi+ebx+3],al ;Write 2nd row to dest
|
||
|
ELSE
|
||
|
mov [edi],al
|
||
|
mov [edi+2],al
|
||
|
mov [edi+ebx+1],al ;Write 2nd row to dest
|
||
|
mov [edi+ebx+3],al ;Write 2nd row to dest
|
||
|
ENDIF
|
||
|
|
||
|
add edi,4 ;Next dest block positionw
|
||
|
dec ecx ;More blocks for this row?
|
||
|
jnz ??Not_finished_a_line
|
||
|
|
||
|
; Advance to the next destination row of blocks.
|
||
|
|
||
|
??Next_row:
|
||
|
mov edi,[edi_startval]
|
||
|
add edi,[rowoffset]
|
||
|
mov [edi_startval],edi
|
||
|
|
||
|
cmp esi,[data_end] ;Have we reached the end of the
|
||
|
jnb short ??End_of_data ; pointers buffer?
|
||
|
jmp ??Start_row
|
||
|
|
||
|
??End_of_data:
|
||
|
IF PHARLAP_TNT
|
||
|
pop es
|
||
|
ENDIF
|
||
|
|
||
|
ret
|
||
|
|
||
|
ENDP UnVQ_4x2_Woofer
|
||
|
ENDIF ;VQABLOCK_4X2
|
||
|
ENDIF ;VQABLOCK_WOOFER
|
||
|
|
||
|
END
|
||
|
|